Skip to content

Era5Source

Classes:

  • Era5Source

    The Era5Source object manages weather data (as netCDF4 files) coming from the

Era5Source

Era5Source(
    source,
    bounds=None,
    index_pad=5,
    time_index_from=None,
    **kwargs,
)

Bases: NCSource

The Era5Source object manages weather data (as netCDF4 files) coming from the ERA5 climate data products<https://www.ecmwf.int/en/forecasts/datasets/reanalysis-datasets/era5>

If furthermore allows access a number of common functionalities and constants which are often encountered when simulating renewable energy technologies

Note:

Various constants can have been set for this weather source which can impact later simulation workflows.

These constants include: MAX_LON_DIFFERENCE = 0.26 The maximum longitude difference to accept between a grid cell's center and the coordinates to extract data for

MAX_LAT_DIFFERENCE = 0.26
    The maximum latitude difference to accept between a grid cell's center and the coordinates
        to extract data for

WIND_SPEED_HEIGHT_FOR_WIND_ENERGY = 100
    The suggested altitude of wind speed data to use for wind-energy simulations

WIND_SPEED_HEIGHT_FOR_SOLAR_ENERGY = 10
    The suggested altitude of wind speed data to use for wind-energy simulations

LONG_RUN_AVERAGE_WINDSPEED :
    A path to a raster file with the long-time average wind speed in each grid cell
    * Can be used in wind energy simulations
    * Calculated at the height specified in `ELEVATED_WIND_SPEED_HEIGHT`
    * Averaged over 2008 until the end of 2017
    * The averaging is performed globally

LONG_RUN_AVERAGE_WINDDIR :
    A path to a raster file with the long-time average wind direction in each grid cell
    * Can be used in wind energy simulations
    * Calculated at the height specified in `ELEVATED_WIND_SPEED_HEIGHT`
    * Averaged over 2008 until the end of 2017
    * The averaging is performed globally

LONG_RUN_AVERAGE_GHI :
    A path to a raster file with the long-time average global horizontal irradiance in
        each grid cell
    * Can be used in solar energy simulations
    * Calculated at the surface
    * Averaged over 1994 until the end of 2018
    * The averaging is performed globally

LONG_RUN_AVERAGE_DHI :
    A path to a raster file with the long-time average direct horizontal irradiance in
        each grid cell
    * Can be used in solar energy simulations
    * Calculated at the surface and on a horizontal plane (not DNI!)
    * Averaged over 1994 until the end of 2018
    * The averaging is performed globally

LONG_RUN_AVERAGE_DNI :
    A path to a raster file with the long-time average direct normal irradiance in
        each grid cell
    * Can be used in solar energy simulations
    * Derived from the direct horizontal irradiance and the solar elevation angle
    * Averaged over 1994 until the end of 2018
    * The averaging is performed globally
Versioning of the LRA rasters

Each LRA raster carries the year and month it was added to RESKit as a suffix (its "vintage", e.g. _2026_07), on both the file name and the constant. A vintage is never modified after it has been committed, so a simulation that pins a suffixed constant stays reproducible even as newer rasters are added:

# follows the current recommendation, may change between RESKit versions
Era5Source.LONG_RUN_AVERAGE_GHI

# pinned, will always be this exact raster
Era5Source.LONG_RUN_AVERAGE_GHI_2026_07

The unsuffixed names are aliases for the current vintage. Superseded vintages remain available under their own suffix (e.g. LONG_RUN_AVERAGE_GHI_2020_03).

Note that the vintage records when the raster was added, which is independent of the period it averages over -- the averaging period is part of the file name instead.

See Also

reskit.weather.MerraSource reskit.weather.SarahSource reskit.weather.Era5Source

Initialize a ERA5 style netCDF4 file source

Compared to the generic NCSource object, the following parameters are automatically set: * tz = None * time_name = "time" * lat_name = "latitude" * lon_name = "longitude" * flip_lat = True * flip_lon = False * time_offset_minutes = -30

Parameters:

  • path

    (str or list of str) –

    The path to the main data file(s) to load

    If multiple files are given, or if a directory of netCDF4 files is given, then it is assumed that all files ending with the extension '.nc' or '.nc4' should be managed by this object. * Be sure that all the netCDF4 files given share the same time and spatial dimensions!

  • bounds

    (Anything acceptable to geokit.Extent.load(), default: None ) –

    The boundaries of the data which is needed * Usage of this will help with memory management * If None, the full dataset is loaded in memory * The actual extent of the loaded data depends on the source's available data

  • index_pad

    (int, default: 5 ) –

    The padding to apply to the boundaries * Useful in case of interpolation * Units are in longitudinal degrees

  • verbose

    (bool) –

    If True, then status outputs are printed when searching for and reading weather data

  • forward_fill

    (bool) –

    If True, then missing data in the weather file is forward-filled * Generally, there should be no missing data at all. This option is only intended to catch the rare scenarios where one or two timesteps are missing

See Also

MerraSource SarahSource Era5Source

Methods:

Source code in reskit/weather/Era5Source/Era5Source.py
def __init__(self, source, bounds=None, index_pad=5, time_index_from=None, **kwargs):
    """Initialize a ERA5 style netCDF4 file source

    Compared to the generic NCSource object, the following parameters are automatically set:
        * tz = None
        * time_name = "time"
        * lat_name = "latitude"
        * lon_name = "longitude"
        * flip_lat = True
        * flip_lon = False
        * time_offset_minutes = -30


    Parameters
    ----------
    path : str or list of str
        The path to the main data file(s) to load

        If multiple files are given, or if a directory of netCDF4 files is given, then it is assumed
        that all files ending with the extension '.nc' or '.nc4' should be managed by this object.
        * Be sure that all the netCDF4 files given share the same time and spatial dimensions!

    bounds : Anything acceptable to geokit.Extent.load(), optional
        The boundaries of the data which is needed
          * Usage of this will help with memory management
          * If None, the full dataset is loaded in memory
          * The actual extent of the loaded data depends on the source's
            available data

    index_pad : int, optional
        The padding to apply to the boundaries
          * Useful in case of interpolation
          * Units are in longitudinal degrees

    verbose : bool, optional
        If True, then status outputs are printed when searching for and reading weather data

    forward_fill : bool, optional
        If True, then missing data in the weather file is forward-filled
        * Generally, there should be no missing data at all. This option is only intended to
            catch the rare scenarios where one or two timesteps are missing

    See Also
    --------
    MerraSource
    SarahSource
    Era5Source
    """
    # translate the mos common lear names for time_index_from
    ERA5_names = {
        "global_horizontal_irradiance_archive": "ssrd",
        "global_horizontal_irradiance": "ssrd_t_adj",
        "direct_horizontal_irradiance_archive": "fdir",
        "direct_horizontal_irradiance": "fdir_t_adj",
        "surface_wind_speed": "w10",
        "elevated_wind_speed": "w100",
    }
    if time_index_from in ERA5_names.keys():
        # if time_index_from is a known clear name use the dict
        time_index_from = ERA5_names[time_index_from]
    else:
        # hope it is a well known ERA5 string. checks in super.__init__
        pass

    super().__init__(
        source=source,
        bounds=bounds,
        time_name="time",
        lat_name="latitude",
        lon_name="longitude",
        index_pad=index_pad,
        _max_lon_diff=self.MAX_LON_DIFFERENCE,
        _max_lat_diff=self.MAX_LAT_DIFFERENCE,
        tz=None,
        flip_lat=True,
        time_offset_minutes=-30,  # time convention -30
        time_index_from=time_index_from,
        **kwargs,
    )

raw_passthrough_variables classmethod

raw_passthrough_variables(cds_variables)

Return the NC short names that are used raw from the ERA5 download — i.e. the variables that survive preprocessing unchanged, with the ones that get replaced by a preprocessed/derived output (see PREPROCESSED_NC_NAMES) removed.

Parameters:

  • cds_variables

    (iterable of str) –

    The ERA5 CDS API variable names a workflow requires (e.g. ["2m_temperature", "surface_pressure", "100m_u_component_of_wind"]).

Returns:

  • list of str

    The corresponding NC short names that pass through unmodified.

Source code in reskit/weather/Era5Source/Era5Source.py
@classmethod
def raw_passthrough_variables(cls, cds_variables):
    """Return the NC short names that are used raw from the ERA5 download — i.e. the
    variables that survive preprocessing unchanged, with the ones that get replaced by
    a preprocessed/derived output (see ``PREPROCESSED_NC_NAMES``) removed.

    Parameters
    ----------
    cds_variables : iterable of str
        The ERA5 CDS API variable names a workflow requires
        (e.g. ``["2m_temperature", "surface_pressure", "100m_u_component_of_wind"]``).

    Returns
    -------
    list of str
        The corresponding NC short names that pass through unmodified.
    """
    return [
        cls.CDS_TO_NC_NAME[cds_name]
        for cds_name in cds_variables
        if cds_name in cls.CDS_TO_NC_NAME and cls.CDS_TO_NC_NAME[cds_name] not in cls.PREPROCESSED_NC_NAMES
    ]

sload_boundary_layer_height

sload_boundary_layer_height()

Standard loader function for the variable 'boundary_layer_height' in meters from the surface

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_boundary_layer_height(self):
    """Standard loader function for the variable 'boundary_layer_height' in meters
    from the surface

    """
    return self.load("blh", "boundary_layer_height")

sload_direct_horizontal_irradiance

sload_direct_horizontal_irradiance()

Standard loader function for the variable 'direct_horizontal_irradiance'

Automatically reads the variable "fdir" from the given ERA5 source and saves it as the variable 'direct_horizontal_irradiance' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_direct_horizontal_irradiance(self):
    """Standard loader function for the variable 'direct_horizontal_irradiance'

    Automatically reads the variable "fdir" from the given ERA5 source and saves it as the
    variable 'direct_horizontal_irradiance' in the data library
    """
    return self.load("fdir_t_adj", name="direct_horizontal_irradiance")

sload_direct_horizontal_irradiance_archive

sload_direct_horizontal_irradiance_archive()

Standard loader function for the variable 'direct_horizontal_irradiance'

Automatically reads the variable "fdir" from the given ERA5 source and saves it as the variable 'direct_horizontal_irradiance' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_direct_horizontal_irradiance_archive(self):
    """Standard loader function for the variable 'direct_horizontal_irradiance'

    Automatically reads the variable "fdir" from the given ERA5 source and saves it as the
    variable 'direct_horizontal_irradiance' in the data library
    """
    print(
        "WARNING: Non time corrected ERA5-direct_horizontal_irradiance loaded. Only do this, if you understand the implications of this!"
    )
    return self.load("fdir", name="direct_horizontal_irradiance_archive")

sload_elevated_wind_direction

sload_elevated_wind_direction()

Standard loader function for the variable 'elevated_wind_direction'

Automatically reads the variables "wd" from the given ERA5 source and saves it as the variable 'elevated_wind_direction' in the data library

Where '' is the height specified by Era5Source.ELEVATED_WIND_SPEED_HEIGHT

The "wd" variable also needs to be precomputed from the raw variables "u" and "v" and made available in the raw dataset

TODO: Update function to also be able to handle raw ERA5 inputs for u & v

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_elevated_wind_direction(self):
    """Standard loader function for the variable 'elevated_wind_direction'

    Automatically reads the variables "wd<X>" from the given ERA5 source and saves
    it as the variable 'elevated_wind_direction' in the data library

    Where '<X>' is the height specified by `Era5Source.ELEVATED_WIND_SPEED_HEIGHT`

    The "wd<X>" variable also needs to be precomputed from the raw variables "u<X>"
        and "v<X>" and made available in the raw dataset

    TODO: Update function to also be able to handle raw ERA5 inputs for u & v
    """
    return self.load("wd100", "elevated_wind_direction")

sload_elevated_wind_speed

sload_elevated_wind_speed()

Standard loader function for the variable 'elevated_wind_speed'

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_elevated_wind_speed(self):
    """Standard loader function for the variable 'elevated_wind_speed'"""
    return self._sload_wind_speed(height=self.ELEVATED_WIND_SPEED_HEIGHT, target_name="elevated_wind_speed")

sload_global_horizontal_irradiance

sload_global_horizontal_irradiance()

Standard loader function for the variable 'global_horizontal_irradiance'

Automatically reads the variable "ssrd" from the given ERA5 source and saves it as the variable 'global_horizontal_irradiance' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_global_horizontal_irradiance(self):
    """Standard loader function for the variable 'global_horizontal_irradiance'

    Automatically reads the variable "ssrd" from the given ERA5 source and saves it as the
    variable 'global_horizontal_irradiance' in the data library
    """
    return self.load("ssrd_t_adj", name="global_horizontal_irradiance")

sload_global_horizontal_irradiance_archive

sload_global_horizontal_irradiance_archive()

Archive loader function for the variable 'global_horizontal_irradiance. Uses non corrected solar inputs. Use only for reproduceability purposes'

Automatically reads the variable "ssrd" from the given ERA5 source and saves it as the variable 'global_horizontal_irradiance' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_global_horizontal_irradiance_archive(self):
    """Archive loader function for the variable 'global_horizontal_irradiance. Uses non corrected solar inputs.
    Use only for reproduceability purposes'

    Automatically reads the variable "ssrd" from the given ERA5 source and saves it as the
    variable 'global_horizontal_irradiance' in the data library
    """
    print("WARNING: Non time corrected ERA5-GHI loaded. Only do this, if you understand the implications of this!")
    return self.load("ssrd", name="global_horizontal_irradiance_archive")

sload_snow_albedo

sload_snow_albedo()

Standard loader function for the variable 'snow_albedo'

unit: dimensionless, instantaneous

Automatically reads the variable "asn" from the given ERA5 source and saves it as the variable 'snow_albedo' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_snow_albedo(self):
    """Standard loader function for the variable 'snow_albedo'

    unit: dimensionless, instantaneous

    Automatically reads the variable "asn" from the given ERA5 source and saves it as the
    variable 'snow_albedo' in the data library
    """
    return self.load("asn", name="snow_albedo")

sload_snow_density

sload_snow_density()

Standard loader function for the variable 'snow_density'

unit: kg/m^3, instantaneous

Automatically reads the variable "rsn" from the given ERA5 source and saves it as the variable 'snow_density' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_snow_density(self):
    """Standard loader function for the variable 'snow_density'

    unit: kg/m^3, instantaneous

    Automatically reads the variable "rsn" from the given ERA5 source and saves it as the
    variable 'snow_density' in the data library
    """
    return self.load("rsn", name="snow_density")

sload_snow_depth_water_equivalent

sload_snow_depth_water_equivalent()

Standard loader function for the variable 'snow_depth_water_equivalent'

unit: meters, instantaneous

Automatically reads the variable "sd" from the given ERA5 source and saves it as the variable 'snow_depth_water_equivalent' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_snow_depth_water_equivalent(self):
    """Standard loader function for the variable 'snow_depth_water_equivalent'

    unit: meters, instantaneous

    Automatically reads the variable "sd" from the given ERA5 source and saves it as the
    variable 'snow_depth_water_equivalent' in the data library
    """
    return self.load("sd", name="snow_depth_water_equivalent")

sload_snowfall_water_equivalent

sload_snowfall_water_equivalent()

Standard loader function for the variable 'snowfall_water_equivalent'

unit: meters per time step, accumulation

Automatically reads the variable "sf" from the given ERA5 source and saves it as the variable 'snowfall_water_equivalent' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_snowfall_water_equivalent(self):
    """Standard loader function for the variable 'snowfall_water_equivalent'

    unit: meters per time step, accumulation

    Automatically reads the variable "sf" from the given ERA5 source and saves it as the
    variable 'snowfall_water_equivalent' in the data library
    """
    return self.load("sf", name="snowfall_water_equivalent")

sload_surface_air_temperature

sload_surface_air_temperature()

Standard loader function for the variable 'surface_air_temperature'

Automatically reads the variable "t2m" from the given ERA5 source and saves it as the variable 'surface_air_temperature' in the data library

Temperature values are also converted from kelvin to degrees celsius

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_surface_air_temperature(self):
    """Standard loader function for the variable 'surface_air_temperature'

    Automatically reads the variable "t2m" from the given ERA5 source and saves it as the
    variable 'surface_air_temperature' in the data library

    Temperature values are also converted from kelvin to degrees celsius
    """
    return self.load("t2m", name="surface_air_temperature", processor=lambda x: x - 273.15)

sload_surface_dew_temperature

sload_surface_dew_temperature()

Standard loader function for the variable 'surface_dew_temperature'

Automatically reads the variable "d2m" from the given ERA5 source and saves it as the variable 'surface_dew_temperature' in the data library

Temperature values are also converted from kelvin to degrees celsius

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_surface_dew_temperature(self):
    """Standard loader function for the variable 'surface_dew_temperature'

    Automatically reads the variable "d2m" from the given ERA5 source and saves it as the
    variable 'surface_dew_temperature' in the data library

    Temperature values are also converted from kelvin to degrees celsius
    """
    return self.load("d2m", name="surface_dew_temperature", processor=lambda x: x - 273.15)

sload_surface_pressure

sload_surface_pressure()

Standard loader function for the variable 'surface_pressure'

Automatically reads the variable "sp" from the given ERA5 source and saves it as the variable 'surface_pressure' in the data library

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_surface_pressure(self):
    """Standard loader function for the variable 'surface_pressure'

    Automatically reads the variable "sp" from the given ERA5 source and saves it as the
    variable 'surface_pressure' in the data library
    """
    return self.load("sp", name="surface_pressure")

sload_surface_wind_speed

sload_surface_wind_speed()

Standard loader function for the variable 'surface_wind_speed'

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_surface_wind_speed(self):
    """Standard loader function for the variable 'surface_wind_speed'"""
    return self._sload_wind_speed(height=self.SURFACE_WIND_SPEED_HEIGHT, target_name="surface_wind_speed")

sload_wind_speed_at_100m

sload_wind_speed_at_100m()

Standard loader function for the variable 'wind_speed_at_100m'

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_wind_speed_at_100m(self):
    """Standard loader function for the variable 'wind_speed_at_100m'"""
    return self._sload_wind_speed(height=100, target_name="wind_speed_at_100m")

sload_wind_speed_at_10m

sload_wind_speed_at_10m()

Standard loader function for the variable 'wind_speed_at_10m'

Source code in reskit/weather/Era5Source/Era5Source.py
def sload_wind_speed_at_10m(self):
    """Standard loader function for the variable 'wind_speed_at_10m'"""
    return self._sload_wind_speed(height=10, target_name="wind_speed_at_10m")