Skip to content

Commit 794cc5d

Browse files
Create nasa_power.py
1 parent 908d3da commit 794cc5d

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

pvlib/iotools/nasa_power.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
"""Function for reading and retrieving data from NASA POWER."""
2+
3+
import pandas as pd
4+
import requests
5+
6+
7+
URL = 'https://power.larc.nasa.gov/api/temporal/hourly/point'
8+
9+
VARIABLE_MAP = {
10+
'ALLSKY_SFC_SW_DWN': 'ghi',
11+
'ALLSKY_SFC_SW_DIFF': 'dhi',
12+
'ALLSKY_SFC_SW_DNI': 'dni',
13+
'CLRSKY_SFC_SW_DWN': 'ghi_clear',
14+
'T2M': 'temp_air_2m',
15+
'WS2M': 'wind_speed_2m',
16+
'WS10M': 'wind_speed_10m',
17+
}
18+
19+
20+
def get_nasa_power(latitude, longitude, start_date, end_date,
21+
parameters, time_standard='utc', community='re',
22+
site_elevation=None, wind_elevation=None,
23+
wind_surface=None, map_variables=True):
24+
"""
25+
Retrieve irradiance and weather data from NASA POWER.
26+
27+
A general description of NASA POWER is given in [1]_ and the API is
28+
described in [2]_. A detailed list of the available parameters can be
29+
found in [3]_.
30+
31+
Parameters
32+
----------
33+
latitude: float
34+
In decimal degrees, north is positive (ISO 19115).
35+
longitude: float
36+
In decimal degrees, east is positive (ISO 19115).
37+
start_date: datetime like
38+
First timestamp of the requested period. If a timezone is not
39+
specified, UTC is assumed.
40+
end_date: datetime like
41+
Last timestamp of the requested period. If a timezone is not
42+
specified, UTC is assumed.
43+
parameters: str, list
44+
List of parameters. Some common parameters are mentioned below; for the
45+
full list see [3]_:
46+
* ALLSKY_SFC_SW_DWN: Global Horizontal Irradiance (GHI) [Wm⁻²]
47+
* ALLSKY_SFC_SW_DIFF: Diffuse Horizonatl Irradiance (DHI) [Wm⁻²]
48+
* ALLSKY_SFC_SW_DNI: Direct Normal Irradiance (DNI) [Wm⁻²]
49+
* CLRSKY_SFC_SW_DWN: Clear-sky GHI [Wm⁻²]
50+
* T2M : Air temperature at 2 m [C]
51+
* WS2M: Wind speed at 2 m [m/s]
52+
* WS10M: Wind speed at 10 m [m/s]
53+
community: str, default: 're'
54+
Can be one of the following depending on which parameters are of
55+
interest. Note that in many cases this choice might affect the units
56+
of the parameter:
57+
* 're': renewable energy
58+
* 'sb': sustainable buildings
59+
* 'ag': agroclimatology
60+
time_standard: str, default:'utc'
61+
Can be either:
62+
* Universal Time Coordinated (utc): is the standard time measure
63+
used by the world.
64+
* Local Solar Time (lst): A 15 Degrees swath that represents solar
65+
noon at the middle longitude of the swath.
66+
site_elevation: float, optional
67+
The custom site elevation in meters to produce the corrected
68+
atmospheric pressure adjusted for elevation.
69+
wind_elevation: float, optional
70+
The custom wind elevation in meters to produce the wind speed adjusted
71+
for elevation. Has to be between 10 and 300 m; see [4]_.
72+
wind_surface: str, optional
73+
The definable surface type to adjust the wind speed. For a list of the
74+
surface types see [4]_.
75+
map_variables: bool, default: True
76+
When true, renames columns of the Dataframe to pvlib variable names
77+
where applicable. The default is True. See variable
78+
:const:`VARIABLE_MAP`.
79+
80+
Raises
81+
------
82+
requests.HTTPError
83+
Raises an error when an incorrect request is made.
84+
ValueError
85+
Raises an error if more than 15 parameters are requested in one call.
86+
87+
Returns
88+
-------
89+
data : pd.DataFrame
90+
Time series data. The index corresponds to the start (left) of the
91+
interval.
92+
93+
References
94+
----------
95+
.. [1] `NASA Prediction Of Worldwide Energy Resources (POWER)
96+
<https://power.larc.nasa.gov/>`_
97+
.. [2] `NASA POWER API
98+
<https://power.larc.nasa.gov/api/pages/>`_
99+
.. [3] `NASA POWER API parameters
100+
<https://power.larc.nasa.gov/parameters/>`_
101+
.. [4] `NASA POWER corrected wind speed parameters
102+
<https://power.larc.nasa.gov/docs/methodology/meteorology/wind/>_
103+
"""
104+
if len(parameters) > 15:
105+
raise ValueError("A maximum of 15 parameters can currently be "
106+
"requested in one submission.")
107+
108+
start = pd.Timestamp(start_date)
109+
end = pd.Timestamp(end_date)
110+
start = start.tz_localize('UTC') if start.tzinfo is None else start
111+
end = end.tz_localize('UTC') if end.tzinfo is None else end
112+
113+
params = {
114+
'latitude': latitude,
115+
'longitude': longitude,
116+
'start': start.strftime('%Y%m%d'),
117+
'end': end.strftime('%Y%m%d'),
118+
'community': community,
119+
'parameters': ','.join(parameters), # make parameters in a string
120+
'format': 'json',
121+
'user': None,
122+
'header': True,
123+
'time-standard': time_standard,
124+
'site-elevation': site_elevation,
125+
'wind-elevation': wind_elevation,
126+
'wind-surface': wind_surface,
127+
}
128+
129+
response = requests.get(URL, params=params)
130+
if not response.ok:
131+
# response.raise_for_status() does not give a useful error message
132+
raise requests.HTTPError(response.json())
133+
134+
# Parse the data to dataframe
135+
data = response.json()
136+
hourly_data = data['properties']['parameter']
137+
df = pd.DataFrame(hourly_data)
138+
df.index = pd.to_datetime(df.index, format='%Y%m%d%H')
139+
df = df.sort_index()
140+
141+
# Rename according to pvlib convention
142+
if map_variables:
143+
df = df.rename(columns=VARIABLE_MAP)
144+
145+
return df

0 commit comments

Comments
 (0)