ERA5

The ERA5 class fetches ERA5 reanalysis data (10-m wind speed and precipitation) for a given location and time period. Two backends are supported: open_meteo (no registration required, default) and cds (Copernicus Climate Data Store, requires an API key).

class ecosound.environment.era5.ERA5(source: str = 'open_meteo', cds_url: str | None = None, cds_key: str | None = None, verbose: bool = True)[source]

Bases: object

Class for fetching ERA5 reanalysis 10-m wind and precipitation data at a point location.

ERA5 provides hourly wind data at 0.25° (~28 km) spatial resolution from 1940 to present. The nearest grid point to the requested location is used.

By default, data is fetched via the Open-Meteo API (no registration needed). Set source=”cds” to use the Copernicus CDS API directly (requires a free account and configured ~/.cdsapirc).

Parameters:
  • source – Data backend — “open_meteo” (default) or “cds”.

  • cds_url – CDS API URL override (only used when source=”cds”).

  • cds_key – CDS API key as “UID:key” override (only used when source=”cds”).

  • verbose – Print progress messages (default: True).

wind_timeseries

Most recent wind time series from get_wind_timeseries(). Dimension: time. Coordinates: time, lat, lon. None until first call.

Type:

xr.Dataset | None

precipitation_timeseries

Most recent precipitation time series from get_precipitation_timeseries(). Dimension: time. Coordinates: time, lat, lon. None until first call.

Type:

xr.Dataset | None

Examples

# No registration required (Open-Meteo backend) >>> from ERA5 import ERA5 >>> era5 = ERA5() >>> era5.get_wind_timeseries(lat=42.5, lon=-70.0, … start_dt=”2015-08-01”, end_dt=”2015-08-07”) >>> era5.plot_wind_timeseries()

# CDS backend (requires ~/.cdsapirc) >>> era5_cds = ERA5(source=”cds”) >>> era5_cds.get_wind_timeseries(lat=42.5, lon=-70.0, … start_dt=”2015-08-01”, end_dt=”2015-08-07”)

# Combine with NECOFS (shared time/lat/lon coordinates) >>> ds_wind_aligned = era5.wind_timeseries.sel( … time=ds_ocean.time, method=”nearest”) >>> ds_combined = xr.merge([ds_ocean, ds_wind_aligned])

OPEN_METEO_URL = 'https://archive-api.open-meteo.com/v1/archive'
CDS_DATASET = 'reanalysis-era5-single-levels'
CDS_WIND_VARIABLES = ['10m_u_component_of_wind', '10m_v_component_of_wind']
CDS_PRECIP_VARIABLES = ['total_precipitation', 'snowfall']
GRID_RESOLUTION = 0.25
get_wind_timeseries(lat: float, lon: float, start_dt: datetime | Timestamp | str, end_dt: datetime | Timestamp | str) Dataset[source]

Fetch ERA5 10-m wind data at the nearest grid point for a given location and time range.

The backend used depends on self.source:
  • “open_meteo” (default): no registration needed, uses HTTP GET.

  • “cds”: Copernicus CDS API, requires ~/.cdsapirc.

Both backends return the same xr.Dataset structure. The result is always stored in self.wind_timeseries and always returned, so the method can be used with or without assignment:

era5.get_wind_timeseries(lat, lon, start_dt, end_dt) ds = era5.get_wind_timeseries(lat, lon, start_dt, end_dt)

Parameters:
  • lat – Latitude (decimal degrees, WGS84).

  • lon – Longitude (decimal degrees, WGS84, negative west).

  • start_dt – Start of the time range (inclusive). Accepts datetime, pd.Timestamp, or ISO 8601 string (e.g. “2015-08-01”).

  • end_dt – End of the time range (inclusive).

Returns:

Data variables:
  • u10_ms (time) : 10m eastward wind component (m/s)

  • v10_ms (time) : 10m northward wind component (m/s)

  • wind_speed_ms (time) : 10m wind speed (m/s)

  • wind_dir_deg (time) : 10m wind direction, FROM, met. convention (°)

Coordinates:
  • time : hourly datetime64 (UTC)

  • lat : nearest grid latitude (scalar)

  • lon : nearest grid longitude (scalar)

Dataset.attrs:
  • requested_lat/lon, nearest_grid_lat/lon, source, temporal_resolution, spatial_resolution, wind_height, wind_dir_convention

Return type:

xr.Dataset with dimension time, also stored in self.wind_timeseries

Raises:
  • ImportError – If cdsapi is not installed (source=”cds” only).

  • Exception – If the API request fails (network, quota, etc.).

get_precipitation_timeseries(lat: float, lon: float, start_dt: datetime | Timestamp | str, end_dt: datetime | Timestamp | str) Dataset[source]

Fetch ERA5 hourly precipitation at the nearest grid point for a given location and time range.

The backend used depends on self.source:
  • “open_meteo” (default): no registration needed, uses HTTP GET.

  • “cds”: Copernicus CDS API, requires ~/.cdsapirc.

Both backends return the same xr.Dataset structure. The result is always stored in self.precipitation_timeseries and always returned:

era5.get_precipitation_timeseries(lat, lon, start_dt, end_dt) ds = era5.get_precipitation_timeseries(lat, lon, start_dt, end_dt)

Parameters:
  • lat – Latitude (decimal degrees, WGS84).

  • lon – Longitude (decimal degrees, WGS84, negative west).

  • start_dt – Start of the time range (inclusive). Accepts datetime, pd.Timestamp, or ISO 8601 string (e.g. “2015-08-01”).

  • end_dt – End of the time range (inclusive).

Returns:

Data variables:
  • precipitation_mmh (time): Total precipitation rate (mm/h)

  • rain_mmh (time): Rainfall rate, large-scale + convective (mm/h)

  • snowfall_mmh (time): Snowfall rate, liquid water equivalent (mm/h)

Coordinates:
  • time : hourly datetime64 (UTC)

  • lat : nearest grid latitude (scalar)

  • lon : nearest grid longitude (scalar)

Dataset.attrs:
  • requested_lat/lon, nearest_grid_lat/lon, source, temporal_resolution, spatial_resolution, units_note

Return type:

xr.Dataset with dimension time, also stored in self.precipitation_timeseries

Raises:
  • ImportError – If cdsapi is not installed (source=”cds” only).

  • Exception – If the API request fails (network, quota, etc.).

plot_precipitation_timeseries(figsize: tuple = (12, 6), display: bool = True, filename: str | None = None) None[source]

Plot the precipitation time series stored in self.precipitation_timeseries.

Produces a figure with two stacked subplots sharing the time axis:
  1. Total precipitation rate (mm/h), filled area

  2. Rainfall and snowfall rates (mm/h), stacked filled areas

Each panel is auto-scaled to the data range of that variable.

Parameters:
  • figsize – Figure size as (width, height) in inches (default: (12, 6)).

  • display – Show the figure on screen (default: True).

  • filename – If provided, save the figure to this path (e.g. “precip.png”). Any format supported by matplotlib is accepted. Default: None.

Raises:

RuntimeError – If get_precipitation_timeseries() has not been called yet.

plot_wind_timeseries(figsize: tuple = (12, 7), display: bool = True, filename: str | None = None) None[source]

Plot the wind time series stored in self.wind_timeseries.

Produces a figure with three stacked subplots sharing the time axis:
  1. Wind speed (m/s)

  2. U (eastward) and V (northward) components (m/s), on the same axes

  3. Wind direction (degrees, meteorological convention), as scatter to avoid misleading line artefacts across the 0°/360° wrap

Each panel is auto-scaled to the data range of that variable.

Parameters:
  • figsize – Figure size as (width, height) in inches (default: (12, 7)).

  • display – Show the figure on screen (default: True).

  • filename – If provided, save the figure to this path (e.g. “wind.png”). Any format supported by matplotlib is accepted. Default: None.

Raises:

RuntimeError – If get_wind_timeseries() has not been called yet.