11"""Functions to read NREL MIDC data.
22"""
3- from functools import partial
43import pandas as pd
54
6- # VARIABLE_MAP is a dictionary mapping partial MIDC field names to their
7- # pvlib names. See docstring of read_midc for description.
8-
9- VARIABLE_MAP = {
10- 'Direct' : 'dni' ,
11- 'Global' : 'ghi' ,
12- 'Diffuse' : 'dhi' ,
13- 'Airmass' : 'airmass' ,
14- 'Azimuth Angle' : 'solar_azimuth' ,
15- 'Zenith Angle' : 'solar_zenith' ,
16- 'Air Temperature' : 'temp_air' ,
17- 'Temperature' : 'temp_air' ,
18- 'Dew Point Temp' : 'temp_dew' ,
19- 'Relative Humidity' : 'relative_humidity' ,
20- }
5+
6+ # MIDC_VARIABLE_MAP maps some variables of interest at each MIDC site to their
7+ # pvlib counterparts. The mapping dictionary for a site can be found by looking
8+ # up the Site's id in the dictionary. It is not a comprehensive list, and may
9+ # not be the best fit for your application, but should serve as a base for
10+ # creating your own mappings.
11+ #
12+ # In particular, these mappings coincide with the raw ddata files.
13+ # All site's field list can be found at:
14+ # https://midcdmz.nrel.gov/apps/daily.pl?site=<SITE ID>&live=1
15+ # Where id is the key found in this dictionary
16+ MIDC_VARIABLE_MAP = {
17+ 'BMS' : {
18+ 'Global CMP22 (vent/cor) [W/m^2]' : 'ghi' ,
19+ 'Direct NIP [W/m^2]' : 'dni' ,
20+ 'Diffuse CM22-1 (vent/cor) [W/m^2]' : 'dhi' ,
21+ 'Avg Wind Speed @ 6ft [m/s]' : 'wind_speed' ,
22+ 'Tower Dry Bulb Temp [deg C]' : 'temp_air' ,
23+ 'Tower RH [%]' : 'relative_humidity' },
24+ 'UOSMRL' : {
25+ 'Global CMP22 [W/m^2]' : 'ghi' ,
26+ 'Direct NIP [W/m^2]' : 'dni' ,
27+ 'Diffuse Schenk [W/m^2]' : 'dhi' ,
28+ 'Air Temperature [deg C]' : 'temp_air' ,
29+ 'Relative Humidity [%]' : 'relative_humidity' ,
30+ 'Avg Wind Speed @ 10m [m/s]' : 'wind_speed' },
31+ 'HSU' : {
32+ 'Global Horiz [W/m^2]' : 'ghi' ,
33+ 'Direct Normal (calc) [W/m^2]' : 'dni' ,
34+ 'Diffuse Horiz (band_corr) [W/m^2]' : 'dhi' },
35+ 'UTPASRL' : {
36+ 'Global Horizontal [W/m^2]' : 'ghi' ,
37+ 'Direct Normal [W/m^2]' : 'dni' ,
38+ 'Diffuse Horizontal [W/m^2]' : 'dhi' ,
39+ 'CHP1 Temp [deg C]' : 'temp_air' },
40+ 'UAT' : {
41+ 'Global Horiz (platform) [W/m^2]' : 'ghi' ,
42+ 'Direct Normal [W/m^2]' : 'dni' ,
43+ 'Diffuse Horiz [W/m^2]' : 'dhi' ,
44+ 'Air Temperature [deg C]' : 'temp_air' ,
45+ 'Rel Humidity [%]' : 'relative_humidity' ,
46+ 'Avg Wind Speed @ 3m [m/s]' : 'wind_speed' },
47+ 'STAC' : {
48+ 'Global Horizontal [W/m^2]' : 'ghi' ,
49+ 'Direct Normal [W/m^2]' : 'dni' ,
50+ 'Diffuse Horizontal [W/m^2]' : 'dhi' ,
51+ 'Avg Wind Speed @ 10m [m/s]' : 'wind_speed' ,
52+ 'Air Temperature [deg C]' : 'temp_air' ,
53+ 'Rel Humidity [%]' : 'relative_humidity' },
54+ 'UNLV' : {
55+ 'Global Horiz [W/m^2]' : 'ghi' ,
56+ 'Direct Normal [W/m^2]' : 'dni' ,
57+ 'Diffuse Horiz (calc) [W/m^2]' : 'dhi' ,
58+ 'Dry Bulb Temp [deg C]' : 'temp_air' ,
59+ 'Avg Wind Speed @ 30ft [m/s]' : 'wind_speed' },
60+ 'ORNL' : {
61+ 'Global Horizontal [W/m^2]' : 'ghi' ,
62+ 'Direct Normal [W/m^2]' : 'dni' ,
63+ 'Diffuse Horizontal [W/m^2]' : 'dhi' ,
64+ 'Air Temperature [deg C]' : 'temp_air' ,
65+ 'Rel Humidity [%]' : 'relative_humidity' ,
66+ 'Avg Wind Speed @ 42ft [m/s]' : 'wind_speed' },
67+ 'NELHA' : {
68+ 'Global Horizontal [W/m^2]' : 'ghi' ,
69+ 'Air Temperature [W/m^2]' : 'temp_air' ,
70+ 'Avg Wind Speed @ 10m [m/s]' : 'wind_speed' ,
71+ 'Rel Humidity [%]' : 'relative_humidity' },
72+ 'ULL' : {
73+ 'Global Horizontal [W/m^2]' : 'ghi' ,
74+ 'Direct Normal [W/m^2]' : 'dni' ,
75+ 'Diffuse Horizontal [W/m^2]' : 'dhi' ,
76+ 'Air Temperature [deg C]' : 'temp_air' ,
77+ 'Rel Humidity [%]' : 'relative_humidity' ,
78+ 'Avg Wind Speed @ 3m [m/s]' : 'wind_speed' },
79+ 'VTIF' : {
80+ 'Global Horizontal [W/m^2]' : 'ghi' ,
81+ 'Direct Normal [W/m^2]' : 'dni' ,
82+ 'Diffuse Horizontal [W/m^2]' : 'dhi' ,
83+ 'Air Temperature [deg C]' : 'temp_air' ,
84+ 'Avg Wind Speed @ 3m [m/s]' : 'wind_speed' ,
85+ 'Rel Humidity [%]' : 'relative_humidity' },
86+ 'NWTC' : {
87+ 'Global PSP [W/m^2]' : 'ghi' ,
88+ 'Temperature @ 2m [deg C]' : 'temp_air' ,
89+ 'Avg Wind Speed @ 2m [m/s]' : 'wind_speed' ,
90+ 'Relative Humidity [%]' : 'relative_humidity' }}
91+
2192
2293# Maps problematic timezones to 'Etc/GMT' for parsing.
2394
2798}
2899
29100
30- def map_midc_to_pvlib (variable_map , field_name ):
31- """A mapper function to rename Dataframe columns to their pvlib counterparts.
32-
33- Parameters
34- ----------
35- variable_map: Dictionary
36- A dictionary for mapping MIDC field name to pvlib name. See
37- VARIABLE_MAP for default value and description of how to construct
38- this argument.
39- field_name: string
40- The Column to map.
41-
42- Returns
43- -------
44- label: string
45- The pvlib variable name associated with the MIDC field or the input if
46- a mapping does not exist.
47-
48- Notes
49- -----
50- Will fail if field_name to be mapped matches an entry in VARIABLE_MAP and
51- does not contain brackets. This should not be an issue unless MIDC file
52- headers are updated.
53-
54- """
55- new_field_name = field_name
56- for midc_name , pvlib_name in variable_map .items ():
57- if field_name .startswith (midc_name ):
58- # extract the instrument and units field and then remove units
59- instrument_units = field_name [len (midc_name ):]
60- units_index = instrument_units .find ('[' )
61- instrument = instrument_units [:units_index - 1 ]
62- new_field_name = pvlib_name + instrument .replace (' ' , '_' )
63- break
64- return new_field_name
65-
66-
67101def format_index (data ):
68102 """Create DatetimeIndex for the Dataframe localized to the timezone provided
69103 as the label of the second (time) column.
@@ -114,7 +148,7 @@ def format_index_raw(data):
114148 return data
115149
116150
117- def read_midc (filename , variable_map = VARIABLE_MAP , raw_data = False ):
151+ def read_midc (filename , variable_map = {} , raw_data = False ):
118152 """Read in National Renewable Energy Laboratory Measurement and
119153 Instrumentation Data Center [1]_ weather data.
120154
@@ -123,9 +157,9 @@ def read_midc(filename, variable_map=VARIABLE_MAP, raw_data=False):
123157 filename: string
124158 Filename or url of data to read.
125159 variable_map: dictionary
126- Dictionary for mapping MIDC field names to pvlib names. See variable
127- `VARIABLE_MAP` for default and Notes section below for a description of
128- its format .
160+ Dictionary for mapping MIDC field names to pvlib names. Used to rename
161+ the columns of the resulting DataFrame. Does not map names by default.
162+ See Notes for an example .
129163 raw_data: boolean
130164 Set to true to use format_index_raw to correctly format the date/time
131165 columns of MIDC raw data files.
@@ -137,14 +171,19 @@ def read_midc(filename, variable_map=VARIABLE_MAP, raw_data=False):
137171
138172 Notes
139173 -----
140- Keys of the `variable_map` dictionary should include the first part
141- of a MIDC field name which indicates the variable being measured.
174+ The `variable_map` argument should map fields from MIDC data to pvlib
175+ names.
176+
177+ e.g. If a MIDC file contains the variable 'Global Horizontal [W/m^2]',
178+ passing the dictionary below will rename the column to 'ghi' in
179+ the returned Dataframe.
142180
143- e.g. 'Global PSP [W/m^2]' is entered as a key of 'Global'
181+ {
182+ 'Global Horizontal [W/m^2]': ghi,
183+ }
144184
145- The 'PSP' indicating instrument is appended to the pvlib variable name
146- after mapping to differentiate measurements of the same variable. For a
147- full list of pvlib variable names see the `Variable Style Rules
185+ See the MIDC_VARIABLE_MAP for collection of mappings by site.
186+ For a full list of pvlib variable names see the `Variable Style Rules
148187 <https://pvlib-python.readthedocs.io/en/latest/variables_style_rules.html>`_.
149188
150189 Be sure to check the units for the variables you will use on the
@@ -160,12 +199,11 @@ def read_midc(filename, variable_map=VARIABLE_MAP, raw_data=False):
160199 data = format_index_raw (data )
161200 else :
162201 data = format_index (data )
163- mapper = partial (map_midc_to_pvlib , variable_map )
164- data = data .rename (columns = mapper )
202+ data = data .rename (columns = variable_map )
165203 return data
166204
167205
168- def read_midc_raw_data_from_nrel (site , start , end ):
206+ def read_midc_raw_data_from_nrel (site , start , end , variable_map = {} ):
169207 """Request and read MIDC data directly from the raw data api.
170208
171209 Parameters
@@ -176,6 +214,10 @@ def read_midc_raw_data_from_nrel(site, start, end):
176214 Start date for requested data.
177215 end: datetime
178216 End date for requested data.
217+ variable_map: dict
218+ A dictionary mapping MIDC field names to pvlib names. Used to
219+ rename columns of the resulting DataFrame. See Notes of
220+ :py:func:`pvlib.iotools.read_midc` for example.
179221
180222 Returns
181223 -------
@@ -194,4 +236,4 @@ def read_midc_raw_data_from_nrel(site, start, end):
194236 'end' : end .strftime ('%Y%m%d' )}
195237 endpoint = 'https://midcdmz.nrel.gov/apps/data_api.pl?'
196238 url = endpoint + '&' .join (['{}={}' .format (k , v ) for k , v in args .items ()])
197- return read_midc (url , raw_data = True )
239+ return read_midc (url , variable_map = variable_map , raw_data = True )
0 commit comments