Developer Network NREL NREL Developer Network
# --- # title: Python Examples # summary: NSRDB and SAM Python API examples showing automated download of resource data and SAM simulation # --- #

# #

#
#
#
#
#
#

NSRDB and SAM Python APIs: Automated download of resource data and SAM simulation

#
#
#
#
#
#
# #
#
#
#
#
#
#

This example shows how to use the NSRDB API for automated data download in Section 1 and then provides an example of using these data with the SAM Software Development Kit (SDK) in Section 2. A plotting example is offered in Section 3.

#
#
#
#
#
#
In [1]:
#
#
#
import sys, os
# import pandas as pd
# import numpy as np

# from IPython.display import display
# 
#
#
#
#
#
#
#
#
#
#

1. Request Data From NSRDB using Python API

#
#
#
#
#
#
#

The following section shows how to download NSRDB data for a specified year and location.

#

Declare input variables for api request:

#
#
#
#
#
#
In [2]:
#
#
#
# Declare all variables as strings. Spaces must be replaced with '+', i.e., change 'John Smith' to 'John+Smith'.
# # Define the lat, long of the location and the year
# lat, lon, year = 33.2164, -97.1292, 2010
# # You must request an NSRDB api key from the link above
# api_key = '{{API_KEY}}'
# # Set the attributes to extract (e.g., dhi, ghi, etc.), separated by commas.
# attributes = 'ghi,dhi,dni,wind_speed,air_temperature,solar_zenith_angle'
# # Choose year of data
# year = '2010'
# # Set leap year to true or false. True will return leap day data if present, false will not.
# leap_year = 'false'
# # Set time interval in minutes, i.e., '30' is half hour intervals. Valid intervals are 30 & 60.
# interval = '30'
# # Specify Coordinated Universal Time (UTC), 'true' will use UTC, 'false' will use the local time zone of the data.
# # NOTE: In order to use the NSRDB data in SAM, you must specify UTC as 'false'. SAM requires the data to be in the
# # local time zone.
# utc = 'false'
# # Your full name, use '+' instead of spaces.
# your_name = 'John+Smith'
# # Your reason for using the NSRDB.
# reason_for_use = 'beta+testing'
# # Your affiliation
# your_affiliation = 'my+institution'
# # Your email address
# your_email = 'user@company.com'
# # Please join our mailing list so we can keep you up-to-date on new developments.
# mailing_list = 'true'

# # Declare url string
# url = 'https://developer.nrel.gov/api/nsrdb/v2/solar/psm3-download.csv?wkt=POINT({lon}%20{lat})&names={year}&leap_day={leap}&interval={interval}&utc={utc}&full_name={name}&email={email}&affiliation={affiliation}&mailing_list={mailing_list}&reason={reason}&api_key={api}&attributes={attr}'.format(year=year, lat=lat, lon=lon, leap=leap_year, interval=interval, utc=utc, name=your_name, email=your_email, mailing_list=mailing_list, affiliation=your_affiliation, reason=reason_for_use, api=api_key, attr=attributes)
# # Return just the first 2 lines to get metadata:
# info = pd.read_csv(url, nrows=1)
# # See metadata for specified properties, e.g., timezone and elevation
# timezone, elevation = info['Local Time Zone'], info['Elevation']
# 
#
#
#
#
#
#
#
In [3]:
#
#
#
# View metadata
# info
# 
#
#
#
#
#
#
#
Out[3]:
#
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
SourceLocation IDCityStateCountryLatitudeLongitudeTime ZoneElevationLocal Time Zone...Cloud Type 11Cloud Type 12Fill Flag 0Fill Flag 1Fill Flag 2Fill Flag 3Fill Flag 4Fill Flag 5Surface Albedo UnitsVersion
0NSRDB693763---33.21-97.14-6203-6...DustSmokeNaNMissing ImageLow IrradianceExceeds ClearskyMissing CLoud PropertiesRayleigh ViolationNaN3.0.6
#

1 rows × 46 columns

#
#
#
#
#
#
#
#
#
In [4]:
#
#
#
# Return all but first 2 lines of csv to get data:
# df = pd.read_csv('https://developer.nrel.gov/api/nsrdb/v2/solar/psm3-download.csv?wkt=POINT({lon}%20{lat})&names={year}&leap_day={leap}&interval={interval}&utc={utc}&full_name={name}&email={email}&affiliation={affiliation}&mailing_list={mailing_list}&reason={reason}&api_key={api}&attributes={attr}'.format(year=year, lat=lat, lon=lon, leap=leap_year, interval=interval, utc=utc, name=your_name, email=your_email, mailing_list=mailing_list, affiliation=your_affiliation, reason=reason_for_use, api=api_key, attr=attributes), skiprows=2)

# # Set the time index in the pandas dataframe:
# df = df.set_index(pd.date_range('1/1/{yr}'.format(yr=year), freq=interval+'Min', periods=525600/int(interval)))

# # take a look
# print('shape:', df.shape)
# df.head()

# 
#
#
#
#
#
#
#
#
#
shape: (17520, 11)
# 
#
#
#
#
Out[4]:
#
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
YearMonthDayHourMinuteGHIDHIDNIWind SpeedTemperatureSolar Zenith Angle
2010-01-01 00:00:00201011000002.9-2167.60
2010-01-01 00:30:002010110300002.7-2169.78
2010-01-01 01:00:00201011100002.5-3168.08
2010-01-01 01:30:002010111300002.4-3163.67
2010-01-01 02:00:00201011200002.4-4158.14
#
#
#
#
#
#
shape: (17520, 22) #
#
#
In [5]:
#
#
#
# Print column names
# print(df.columns.values)
# 
#
#
#
#
#
#
#
#
#
['Year' 'Month' 'Day' 'Hour' 'Minute' 'GHI' 'DHI' 'DNI' 'Wind Speed'
#  'Temperature' 'Solar Zenith Angle']
# 
#
#
#
#
#
['Year' 'Month' 'Day' 'Hour' 'Minute' 'Clearsky DHI' 'Clearsky DNI' # 'Clearsky GHI' 'Cloud Type' 'Dew Point' 'DHI' 'DNI' 'Fill Flag' 'GHI' # 'Snow Depth' 'Solar Zenith Angle' 'Temperature' 'Pressure' # 'Relative Humidity' 'Precipitable Water' 'Wind Direction' 'Wind Speed'] #
#
#
#
#
#

2. SAM Simulation

#
#
#
#
#
#
#
#
#

The following illustrates how to use the NSRDB data in a SAM simulation, using the Python Software Development Kit (SDK).

#
#
#
#
#
#
In [6]:
#
#
#
#import additional module for SAM simulation:
# import site
# # Use site.addsitedir() to set the path to the SAM SDK API. Set path to the python directory.
# site.addsitedir('/Applications/sam-sdk-2015-6-30-r3/languages/python/')
# import PySAM.PySSC as pssc
# # Download PySAM here: https://pypi.org/project/NREL-PySAM/

# ssc = pssc.PySSC()

# # Resource inputs for SAM model:
# # Must be byte strings
# wfd = ssc.data_create()
# ssc.data_set_number(wfd, b'lat', lat)
# ssc.data_set_number(wfd, b'lon', lon)
# ssc.data_set_number(wfd, b'tz', timezone)
# ssc.data_set_number(wfd, b'elev', elevation)
# ssc.data_set_array(wfd, b'year', df.index.year)
# ssc.data_set_array(wfd, b'month', df.index.month)
# ssc.data_set_array(wfd, b'day', df.index.day)
# ssc.data_set_array(wfd, b'hour', df.index.hour)
# ssc.data_set_array(wfd, b'minute', df.index.minute)
# ssc.data_set_array(wfd, b'dn', df['DNI'])
# ssc.data_set_array(wfd, b'df', df['DHI'])
# ssc.data_set_array(wfd, b'wspd', df['Wind Speed'])
# ssc.data_set_array(wfd, b'tdry', df['Temperature'])

# # Create SAM compliant object  
# dat = ssc.data_create()
# ssc.data_set_table(dat, b'solar_resource_data', wfd)
# ssc.data_free(wfd)

# # Specify the system Configuration
# # Set system capacity in MW
# system_capacity = 4
# ssc.data_set_number(dat, b'system_capacity', system_capacity)
# # Set DC/AC ratio (or power ratio). See https://sam.nrel.gov/sites/default/files/content/virtual_conf_july_2013/07-sam-virtual-conference-2013-woodcock.pdf
# ssc.data_set_number(dat, b'dc_ac_ratio', 1.1)
# # Set tilt of system in degrees
# ssc.data_set_number(dat, b'tilt', 25)
# # Set azimuth angle (in degrees) from north (0 degrees)
# ssc.data_set_number(dat, b'azimuth', 180)
# # Set the inverter efficency
# ssc.data_set_number(dat, b'inv_eff', 96)
# # Set the system losses, in percent
# ssc.data_set_number(dat, b'losses', 14.0757)
# # Specify fixed tilt system (0=Fixed, 1=Fixed Roof, 2=1 Axis Tracker, 3=Backtracted, 4=2 Axis Tracker)
# ssc.data_set_number(dat, b'array_type', 0)
# # Set ground coverage ratio
# ssc.data_set_number(dat, b'gcr', 0.4)
# # Set constant loss adjustment
# ssc.data_set_number(dat, b'adjust:constant', 0)

# # execute and put generation results back into dataframe
# mod = ssc.module_create(b'pvwattsv5')
# ssc.module_exec(mod, dat)
# df[b'generation'] = np.array(ssc.data_get_array(dat, b'gen'))

# # free the memory
# ssc.data_free(dat)
# ssc.module_free(mod)
# 
#
#
#
#
#
#
#
#
#
#

Check the capacity Factor

#
#
#
#
#
#
In [7]:
#
#
#
# Divide sum of generation by the number of periods times the system size
# df[b'generation'].sum() / (525600/int(interval) * system_capacity)
# 
#
#
#
#
#
#
#
Out[7]:
#
#
0.17417854667732946
#
#
#
#
#
#
#
#
In [8]:
#
#
#
# Total Energy:
# df[b'generation'].sum()
# 
#
#
#
#
#
#
#
Out[8]:
#
#
12206.432551147249
#
#
#
#
#
#
#
#
#
#
#

3. Plot the SAM simulation results

#
#
#
#
#
#
#
#
#

Define a plotting function using matplotlib

#
#
#
#
#
#
In [9]:
#
#
#
%matplotlib inline
# from matplotlib import pyplot as plt

# plt.style.use('ggplot')

# def nsrdb_plot(df, i):
#     fig = plt.figure()
#     ax = fig.add_subplot(111)
#     ax2 = ax.twinx()
#     df['90 Degree Zenith'] = 90
#     df[['GHI', 'DNI', 'DHI', 'Solar Zenith Angle', '90 Degree Zenith']][i:i+int(interval)].plot(ax=ax, figsize=(15,8), yticks=(np.arange(0,900,100)), style={'90 Degree Zenith': '--','Solar Zenith Angle': '-o', 'DNI': '-o', 'DHI': '-o', 'GHI': '-o'}, legend=False)
#     df[b'generation'][i:i+30].plot(ax=ax2, yticks=(np.arange(0,4.5,0.5)), style={'generation': 'y-o'})
#     ax.grid()
#     ax.set_ylabel('W/m2')
#     ax2.set_ylabel('kW')
#     ax.legend(loc=2, ncol=5, frameon=False)
#     ax2.legend(loc=1, frameon=False)
# 
#
#
#
#
#
#
#
#
#
#

Take a look at the results

#
#
#
#
#
#
In [10]:
#
#
#
nsrdb_plot(df, 5050)
# 
#
#
#
#
#
#
#
#
# #
#
#
#
#
#
#
Help Improve this Content