Source code for pvlib.iotools.nasa_power

"""Functions for reading and retrieving data from NASA POWER."""

import pandas as pd
import requests
import numpy as np

URL = 'https://power.larc.nasa.gov/api/temporal/hourly/point'

DEFAULT_PARAMETERS = [
    'dni', 'dhi', 'ghi', 'temp_air', 'wind_speed'
]

VARIABLE_MAP = {
    'ALLSKY_SFC_SW_DWN': 'ghi',
    'ALLSKY_SFC_SW_DIFF': 'dhi',
    'ALLSKY_SFC_SW_DNI': 'dni',
    'CLRSKY_SFC_SW_DWN': 'ghi_clear',
    'T2M': 'temp_air',
    'WS2M': 'wind_speed_2m',
    'WS10M': 'wind_speed',
}


[docs] def get_nasa_power(latitude, longitude, start, end, parameters=DEFAULT_PARAMETERS, *, community='re', elevation=None, wind_height=None, wind_surface=None, map_variables=True, url=URL): """ Retrieve irradiance and weather data from NASA POWER. A general description of NASA POWER is given in [1]_ and the API is described in [2]_. A detailed list of the available parameters can be found in [3]_. Parameters ---------- latitude: float In decimal degrees, north is positive (ISO 19115). longitude: float In decimal degrees, east is positive (ISO 19115). start: datetime like First timestamp of the requested period. end: datetime like Last timestamp of the requested period. parameters: str, list List of parameters. The default parameters are mentioned below; for the full list see [3]_. Note that the pvlib naming conventions can also be used. * Global Horizontal Irradiance (GHI) [Wm⁻²] * Diffuse Horizontal Irradiance (DHI) [Wm⁻²] * Direct Normal Irradiance (DNI) [Wm⁻²] * Air temperature at 2 m [C] * Wind speed at 10 m [m/s] community: str, default 're' Can be one of the following depending on which parameters are of interest. Note that in many cases this choice might affect the units of the parameter. * ``'re'``: renewable energy * ``'sb'``: sustainable buildings * ``'ag'``: agroclimatology elevation: float, optional The custom site elevation in meters to produce the corrected atmospheric pressure adjusted for elevation. wind_height: float, optional The custom wind height in meters to produce the wind speed adjusted for height. Has to be between 10 and 300 m; see [4]_. wind_surface: str, optional The definable surface type to adjust the wind speed. For a list of the surface types see [4]_. If you provide a wind surface alias please include a site elevation with the request. map_variables: bool, default True When true, renames columns of the Dataframe to pvlib variable names where applicable. See variable :const:`VARIABLE_MAP`. Raises ------ requests.HTTPError Raises an error when an incorrect request is made. Returns ------- data : pd.DataFrame Time series data. The index corresponds to the start (left) of the interval. meta : dict Metadata. References ---------- .. [1] `NASA Prediction Of Worldwide Energy Resources (POWER) <https://power.larc.nasa.gov/>`_ .. [2] `NASA POWER API <https://power.larc.nasa.gov/api/pages/>`_ .. [3] `NASA POWER API parameters <https://power.larc.nasa.gov/parameters/>`_ .. [4] `NASA POWER corrected wind speed parameters <https://power.larc.nasa.gov/docs/methodology/meteorology/wind/>`_ """ start = pd.Timestamp(start) end = pd.Timestamp(end) # allow the use of pvlib parameter names parameter_dict = {v: k for k, v in VARIABLE_MAP.items()} parameters = [parameter_dict.get(p, p) for p in parameters] params = { 'latitude': latitude, 'longitude': longitude, 'start': start.strftime('%Y%m%d'), 'end': end.strftime('%Y%m%d'), 'community': community, 'parameters': ','.join(parameters), # make parameters in a string 'format': 'json', 'user': None, 'header': True, 'time-standard': 'utc', 'site-elevation': elevation, 'wind-elevation': wind_height, 'wind-surface': wind_surface, } response = requests.get(url, params=params) if not response.ok: # response.raise_for_status() does not give a useful error message raise requests.HTTPError(response.json()) # Parse the data to dataframe data = response.json() hourly_data = data['properties']['parameter'] df = pd.DataFrame(hourly_data) df.index = pd.to_datetime(df.index, format='%Y%m%d%H').tz_localize('UTC') # Create metadata dictionary meta = data['header'] meta['times'] = data['times'] meta['parameters'] = data['parameters'] meta['longitude'] = data['geometry']['coordinates'][0] meta['latitude'] = data['geometry']['coordinates'][1] meta['altitude'] = data['geometry']['coordinates'][2] # Replace NaN values df = df.replace(meta['fill_value'], np.nan) # Rename according to pvlib convention if map_variables: df = df.rename(columns=VARIABLE_MAP) return df, meta