Core Utilities

The nereus.core module provides fundamental utilities for coordinate transformations, grid operations, mesh handling, spatial queries, and type definitions.

Type Definitions

Type aliases and protocols for nereus.

class nereus.core.types.HasCoordinates(*args, **kwargs)[source]

Bases: Protocol

Protocol for objects with lon/lat coordinates.

property lon: ndarray[tuple[Any, ...], dtype[floating]]

Longitude array in degrees.

property lat: ndarray[tuple[Any, ...], dtype[floating]]

Latitude array in degrees.

__init__(*args, **kwargs)
class nereus.core.types.HasArea(*args, **kwargs)[source]

Bases: Protocol

Protocol for objects with cell area.

property area: ndarray[tuple[Any, ...], dtype[floating]]

Cell area in square meters.

__init__(*args, **kwargs)
class nereus.core.types.MeshProtocol(*args, **kwargs)[source]

Bases: HasCoordinates, HasArea, Protocol

Protocol for model mesh objects.

nereus.core.types.is_dask_array(x)[source]

Check if array is a dask array.

Parameters:

x (array_like) – Input array (numpy, dask, or xarray).

Returns:

True if the underlying data is a dask array.

Return type:

bool

nereus.core.types.wrap_as_xarray(result, source_data, default_name, *, skip_dims=1)[source]

Wrap a reduced result as an xarray DataArray.

After a spatial reduction (e.g. nansum over trailing axes), the result has a subset of the input’s dimensions. This helper preserves dimension names, coordinates, variable name, and attributes when the input is an xarray DataArray.

Parameters:
  • result (float or ndarray) – The reduced result (scalar or array with leading dims).

  • source_data (array_like) – The original input data (used to extract dimension metadata).

  • default_name (str) – Variable name to use when the input has no name (e.g. numpy).

  • skip_dims (int) – Number of trailing dimensions of source_data that were consumed by the reduction and should not appear in the output. Default 1 (spatial-only reduction like ice_area). Use 2 for reductions over (nlevels, npoints) like volume_mean.

nereus.core.types.get_array_data(x)[source]

Extract underlying array data, preserving dask arrays.

This function extracts the underlying array from xarray DataArrays while preserving dask arrays (no eager computation).

Parameters:

x (array_like) – Input array (numpy, dask, or xarray).

Returns:

The underlying array data.

Return type:

ndarray or dask.array

Type Aliases

The following type aliases are defined for convenience:

  • ArrayLike: Union[NDArray[np.floating], xr.DataArray] - Array-like data type

  • FloatArray: NDArray[np.floating] - Float array type

  • IntArray: NDArray[np.integer] - Integer array type

  • BoolArray: NDArray[np.bool_] - Boolean array type

Mesh Utilities

Core mesh utilities for nereus.

This module provides utilities for creating, validating, and normalizing mesh datasets. Meshes are represented as xr.Dataset objects with standardized variable names.

nereus.core.mesh.should_use_dask(npoints, use_dask=None)[source]

Determine whether to use dask arrays based on mesh size.

Parameters:
  • npoints (int) – Number of mesh points.

  • use_dask (bool, optional) – Explicit setting. If None, auto-detects based on threshold.

Returns:

Whether to use dask arrays.

Return type:

bool

nereus.core.mesh.normalize_lon(lon, convention='pm180')[source]

Normalize longitude to specified convention.

Parameters:
  • lon (array_like) – Longitude values in degrees.

  • convention ({"pm180", "0360"}) – Target convention: - “pm180”: [-180, 180] - “0360”: [0, 360]

Returns:

Normalized longitude values.

Return type:

ndarray

nereus.core.mesh.ensure_lon_pm180(ds)[source]

Ensure longitude is normalized to [-180, 180].

Parameters:

ds (xr.Dataset) – Mesh dataset with ‘lon’ variable.

Returns:

Dataset with normalized longitude.

Return type:

xr.Dataset

nereus.core.mesh.validate_mesh(ds, strict=False)[source]

Validate mesh dataset against nereus conventions.

Parameters:
  • ds (xr.Dataset) – Dataset to validate.

  • strict (bool) – If True, raise ValueError on validation errors.

Returns:

List of validation warnings/errors.

Return type:

list of str

Raises:

ValueError – If strict=True and validation fails.

nereus.core.mesh.add_mesh_metadata(ds, mesh_type, source_path=None, use_dask=False)[source]

Add nereus mesh metadata to dataset.

Parameters:
  • ds (xr.Dataset) – Mesh dataset.

  • mesh_type (str) – Mesh type: “fesom”, “healpix”, “nemo”, “lonlat”.

  • source_path (str or Path, optional) – Path to original mesh files.

  • use_dask (bool) – Whether dask arrays are used.

Returns:

Dataset with metadata attributes.

Return type:

xr.Dataset

nereus.core.mesh.is_nereus_mesh(ds)[source]

Check if dataset is a nereus mesh.

Parameters:

ds (xr.Dataset) – Dataset to check.

Returns:

True if dataset has nereus mesh metadata.

Return type:

bool

nereus.core.mesh.get_mesh_type(ds)[source]

Get mesh type from nereus mesh dataset.

Parameters:

ds (xr.Dataset) – Mesh dataset.

Returns:

Mesh type, or None if not a nereus mesh.

Return type:

str or None

nereus.core.mesh.create_lonlat_mesh(resolution, *, lon_bounds=(-180, 180), lat_bounds=(-90, 90), use_dask=None)[source]

Create regular lon-lat mesh.

Parameters:
  • resolution (float or tuple) – Grid resolution in degrees. If tuple, (dlon, dlat).

  • lon_bounds (tuple) – Longitude bounds (min, max).

  • lat_bounds (tuple) – Latitude bounds (min, max).

  • use_dask (bool, optional) – Whether to use dask arrays. Auto-detects if None.

Returns:

Mesh dataset with flattened lon, lat, area.

Return type:

xr.Dataset

nereus.core.mesh.mesh_from_arrays(lon, lat, *, area=None, use_dask=None)[source]

Create mesh from existing coordinate arrays.

Handles 1D, 2D, and regular grid side coordinates. If lon and lat are both 1D but have different sizes, they are treated as regular grid side coordinates and expanded via meshgrid before flattening. 2D arrays are flattened directly.

Parameters:
  • lon (array_like) – Longitude coordinates in degrees.

  • lat (array_like) – Latitude coordinates in degrees.

  • area (array_like, optional) – Cell areas in m^2. If None, estimates from grid spacing.

  • use_dask (bool, optional) – Whether to use dask arrays. Auto-detects if None.

Returns:

Mesh dataset with lon, lat, area.

Return type:

xr.Dataset

Mesh Creation

nereus.core.mesh.create_lonlat_mesh(resolution, *, lon_bounds=(-180, 180), lat_bounds=(-90, 90), use_dask=None)[source]

Create regular lon-lat mesh.

Parameters:
  • resolution (float or tuple) – Grid resolution in degrees. If tuple, (dlon, dlat).

  • lon_bounds (tuple) – Longitude bounds (min, max).

  • lat_bounds (tuple) – Latitude bounds (min, max).

  • use_dask (bool, optional) – Whether to use dask arrays. Auto-detects if None.

Returns:

Mesh dataset with flattened lon, lat, area.

Return type:

xr.Dataset

nereus.core.mesh.mesh_from_arrays(lon, lat, *, area=None, use_dask=None)[source]

Create mesh from existing coordinate arrays.

Handles 1D, 2D, and regular grid side coordinates. If lon and lat are both 1D but have different sizes, they are treated as regular grid side coordinates and expanded via meshgrid before flattening. 2D arrays are flattened directly.

Parameters:
  • lon (array_like) – Longitude coordinates in degrees.

  • lat (array_like) – Latitude coordinates in degrees.

  • area (array_like, optional) – Cell areas in m^2. If None, estimates from grid spacing.

  • use_dask (bool, optional) – Whether to use dask arrays. Auto-detects if None.

Returns:

Mesh dataset with lon, lat, area.

Return type:

xr.Dataset

Mesh Validation

nereus.core.mesh.validate_mesh(ds, strict=False)[source]

Validate mesh dataset against nereus conventions.

Parameters:
  • ds (xr.Dataset) – Dataset to validate.

  • strict (bool) – If True, raise ValueError on validation errors.

Returns:

List of validation warnings/errors.

Return type:

list of str

Raises:

ValueError – If strict=True and validation fails.

nereus.core.mesh.is_nereus_mesh(ds)[source]

Check if dataset is a nereus mesh.

Parameters:

ds (xr.Dataset) – Dataset to check.

Returns:

True if dataset has nereus mesh metadata.

Return type:

bool

nereus.core.mesh.get_mesh_type(ds)[source]

Get mesh type from nereus mesh dataset.

Parameters:

ds (xr.Dataset) – Mesh dataset.

Returns:

Mesh type, or None if not a nereus mesh.

Return type:

str or None

Coordinate Normalization

nereus.core.mesh.normalize_lon(lon, convention='pm180')[source]

Normalize longitude to specified convention.

Parameters:
  • lon (array_like) – Longitude values in degrees.

  • convention ({"pm180", "0360"}) – Target convention: - “pm180”: [-180, 180] - “0360”: [0, 360]

Returns:

Normalized longitude values.

Return type:

ndarray

nereus.core.mesh.ensure_lon_pm180(ds)[source]

Ensure longitude is normalized to [-180, 180].

Parameters:

ds (xr.Dataset) – Mesh dataset with ‘lon’ variable.

Returns:

Dataset with normalized longitude.

Return type:

xr.Dataset

Dask Support

nereus.core.mesh.should_use_dask(npoints, use_dask=None)[source]

Determine whether to use dask arrays based on mesh size.

Parameters:
  • npoints (int) – Number of mesh points.

  • use_dask (bool, optional) – Explicit setting. If None, auto-detects based on threshold.

Returns:

Whether to use dask arrays.

Return type:

bool

nereus.core.mesh.DASK_THRESHOLD_POINTS

Number of points above which dask arrays are automatically used: 1_000_000

Spatial Functions

Spatial query functions for nereus.

Standalone functions for spatial operations on coordinate arrays.

nereus.core.spatial.find_nearest(lon, lat, query_lon, query_lat, k=1, *, return_distance=False)[source]

Find nearest mesh points to query locations.

Uses a KDTree built on Cartesian coordinates for efficient spherical nearest-neighbor search.

Parameters:
  • lon (array_like) – Longitude coordinates of mesh points in degrees.

  • lat (array_like) – Latitude coordinates of mesh points in degrees.

  • query_lon (float or array_like) – Query longitude(s) in degrees.

  • query_lat (float or array_like) – Query latitude(s) in degrees.

  • k (int) – Number of nearest neighbors to find.

  • return_distance (bool) – If True, also return distances in meters.

Returns:

  • indices (ndarray) – Indices of nearest mesh points. Shape depends on inputs: - Scalar query, k=1: scalar int - Scalar query, k>1: (k,) array - Array query, k=1: (n_queries,) array - Array query, k>1: (n_queries, k) array

  • distances (ndarray, optional) – Distances in meters. Returned only if return_distance=True. Same shape as indices.

Return type:

ndarray[tuple[Any, …], dtype[int64]] | tuple[ndarray[tuple[Any, …], dtype[int64]], ndarray[tuple[Any, …], dtype[floating]]]

Examples

>>> mesh = nr.fesom.load_mesh(path)
>>> idx = nr.find_nearest(mesh["lon"].values, mesh["lat"].values, -30.5, 60.2)
>>> print(f"Nearest point: ({mesh['lon'].values[idx]}, {mesh['lat'].values[idx]})")
>>> # Find 3 nearest neighbors with distances
>>> indices, distances = nr.find_nearest(
...     mesh["lon"].values, mesh["lat"].values,
...     [-30, -31], [60, 61],
...     k=3,
...     return_distance=True,
... )
nereus.core.spatial.subset_by_bbox(lon, lat, lon_min, lon_max, lat_min, lat_max)[source]

Get mask for points within bounding box.

Parameters:
  • lon (array_like) – Longitude coordinates in degrees.

  • lat (array_like) – Latitude coordinates in degrees.

  • lon_min (float) – Longitude bounds in degrees.

  • lon_max (float) – Longitude bounds in degrees.

  • lat_min (float) – Latitude bounds in degrees.

  • lat_max (float) – Latitude bounds in degrees.

Returns:

mask – Boolean mask of points within bounds.

Return type:

ndarray

Examples

>>> mesh = nr.fesom.load_mesh(path)
>>> mask = nr.subset_by_bbox(
...     mesh["lon"].values, mesh["lat"].values,
...     lon_min=-10, lon_max=10,
...     lat_min=-5, lat_max=5,
... )
>>> equatorial_area = mesh["area"].values[mask].sum()
nereus.core.spatial.points_in_polygon(lon, lat, polygon_lon, polygon_lat)[source]

Get mask for points inside polygon.

Uses matplotlib.path for point-in-polygon testing.

Parameters:
  • lon (array_like) – Longitude coordinates of mesh points in degrees.

  • lat (array_like) – Latitude coordinates of mesh points in degrees.

  • polygon_lon (array_like) – Longitude coordinates of polygon vertices.

  • polygon_lat (array_like) – Latitude coordinates of polygon vertices.

Returns:

mask – Boolean mask of points inside polygon.

Return type:

ndarray

Notes

The polygon is assumed to be defined in Cartesian lon-lat space (not geodesic). For large-scale polygons crossing the dateline, consider normalizing longitudes first.

Examples

>>> # Select points in a triangular region
>>> poly_lon = [-10, 10, 0, -10]
>>> poly_lat = [0, 0, 10, 0]
>>> mask = nr.points_in_polygon(lon, lat, poly_lon, poly_lat)
nereus.core.spatial.haversine_distance(lon1, lat1, lon2, lat2)[source]

Compute great-circle distance between points using Haversine formula.

Parameters:
  • lon1 (float or array_like) – First point(s) coordinates in degrees.

  • lat1 (float or array_like) – First point(s) coordinates in degrees.

  • lon2 (float or array_like) – Second point(s) coordinates in degrees.

  • lat2 (float or array_like) – Second point(s) coordinates in degrees.

Returns:

distance – Distance in meters.

Return type:

float or ndarray

Examples

>>> d = nr.haversine_distance(-74.0, 40.7, 2.3, 48.9)  # NYC to Paris
>>> print(f"Distance: {d/1000:.0f} km")

Point Queries

nereus.core.spatial.find_nearest(lon, lat, query_lon, query_lat, k=1, *, return_distance=False)[source]

Find nearest mesh points to query locations.

Uses a KDTree built on Cartesian coordinates for efficient spherical nearest-neighbor search.

Parameters:
  • lon (array_like) – Longitude coordinates of mesh points in degrees.

  • lat (array_like) – Latitude coordinates of mesh points in degrees.

  • query_lon (float or array_like) – Query longitude(s) in degrees.

  • query_lat (float or array_like) – Query latitude(s) in degrees.

  • k (int) – Number of nearest neighbors to find.

  • return_distance (bool) – If True, also return distances in meters.

Returns:

  • indices (ndarray) – Indices of nearest mesh points. Shape depends on inputs: - Scalar query, k=1: scalar int - Scalar query, k>1: (k,) array - Array query, k=1: (n_queries,) array - Array query, k>1: (n_queries, k) array

  • distances (ndarray, optional) – Distances in meters. Returned only if return_distance=True. Same shape as indices.

Return type:

ndarray[tuple[Any, …], dtype[int64]] | tuple[ndarray[tuple[Any, …], dtype[int64]], ndarray[tuple[Any, …], dtype[floating]]]

Examples

>>> mesh = nr.fesom.load_mesh(path)
>>> idx = nr.find_nearest(mesh["lon"].values, mesh["lat"].values, -30.5, 60.2)
>>> print(f"Nearest point: ({mesh['lon'].values[idx]}, {mesh['lat'].values[idx]})")
>>> # Find 3 nearest neighbors with distances
>>> indices, distances = nr.find_nearest(
...     mesh["lon"].values, mesh["lat"].values,
...     [-30, -31], [60, 61],
...     k=3,
...     return_distance=True,
... )
nereus.core.spatial.haversine_distance(lon1, lat1, lon2, lat2)[source]

Compute great-circle distance between points using Haversine formula.

Parameters:
  • lon1 (float or array_like) – First point(s) coordinates in degrees.

  • lat1 (float or array_like) – First point(s) coordinates in degrees.

  • lon2 (float or array_like) – Second point(s) coordinates in degrees.

  • lat2 (float or array_like) – Second point(s) coordinates in degrees.

Returns:

distance – Distance in meters.

Return type:

float or ndarray

Examples

>>> d = nr.haversine_distance(-74.0, 40.7, 2.3, 48.9)  # NYC to Paris
>>> print(f"Distance: {d/1000:.0f} km")

Geographic Subsetting

nereus.core.spatial.subset_by_bbox(lon, lat, lon_min, lon_max, lat_min, lat_max)[source]

Get mask for points within bounding box.

Parameters:
  • lon (array_like) – Longitude coordinates in degrees.

  • lat (array_like) – Latitude coordinates in degrees.

  • lon_min (float) – Longitude bounds in degrees.

  • lon_max (float) – Longitude bounds in degrees.

  • lat_min (float) – Latitude bounds in degrees.

  • lat_max (float) – Latitude bounds in degrees.

Returns:

mask – Boolean mask of points within bounds.

Return type:

ndarray

Examples

>>> mesh = nr.fesom.load_mesh(path)
>>> mask = nr.subset_by_bbox(
...     mesh["lon"].values, mesh["lat"].values,
...     lon_min=-10, lon_max=10,
...     lat_min=-5, lat_max=5,
... )
>>> equatorial_area = mesh["area"].values[mask].sum()
nereus.core.spatial.points_in_polygon(lon, lat, polygon_lon, polygon_lat)[source]

Get mask for points inside polygon.

Uses matplotlib.path for point-in-polygon testing.

Parameters:
  • lon (array_like) – Longitude coordinates of mesh points in degrees.

  • lat (array_like) – Latitude coordinates of mesh points in degrees.

  • polygon_lon (array_like) – Longitude coordinates of polygon vertices.

  • polygon_lat (array_like) – Latitude coordinates of polygon vertices.

Returns:

mask – Boolean mask of points inside polygon.

Return type:

ndarray

Notes

The polygon is assumed to be defined in Cartesian lon-lat space (not geodesic). For large-scale polygons crossing the dateline, consider normalizing longitudes first.

Examples

>>> # Select points in a triangular region
>>> poly_lon = [-10, 10, 0, -10]
>>> poly_lat = [0, 0, 10, 0]
>>> mask = nr.points_in_polygon(lon, lat, poly_lon, poly_lat)

Coordinate Functions

Coordinate utilities for nereus.

Functions for converting between geographic and Cartesian coordinates, and for computing distances on the sphere.

nereus.core.coordinates.lonlat_to_cartesian(lon, lat, radius=1.0)[source]

Convert longitude/latitude to Cartesian coordinates.

Parameters:
  • lon (array_like) – Longitude in degrees.

  • lat (array_like) – Latitude in degrees.

  • radius (float, optional) – Radius of the sphere. Default is 1.0 (unit sphere).

Returns:

x, y, z – Cartesian coordinates.

Return type:

tuple of ndarrays

Notes

Uses the convention where: - x points towards (lon=0, lat=0) - y points towards (lon=90, lat=0) - z points towards the North Pole (lat=90)

nereus.core.coordinates.cartesian_to_lonlat(x, y, z)[source]

Convert Cartesian coordinates to longitude/latitude.

Parameters:
  • x (array_like) – Cartesian coordinates.

  • y (array_like) – Cartesian coordinates.

  • z (array_like) – Cartesian coordinates.

Returns:

lon, lat – Longitude and latitude in degrees.

Return type:

tuple of ndarrays

nereus.core.coordinates.meters_to_chord(meters, radius=6371000.0)[source]

Convert distance in meters to chord distance on unit sphere.

The chord distance is the straight-line distance through the sphere between two points, normalized by the sphere radius. This is useful for KDTree queries on unit sphere coordinates.

Parameters:
  • meters (float) – Distance in meters along the surface of the Earth.

  • radius (float, optional) – Earth radius in meters. Default is 6,371,000 m.

Returns:

Chord distance on unit sphere.

Return type:

float

Notes

The formula converts arc length to chord length: chord = 2 * sin(arc_length / (2 * radius))

For small distances, chord ≈ arc_length / radius.

nereus.core.coordinates.chord_to_meters(chord, radius=6371000.0)[source]

Convert chord distance on unit sphere to meters.

Parameters:
  • chord (float) – Chord distance on unit sphere.

  • radius (float, optional) – Earth radius in meters. Default is 6,371,000 m.

Returns:

Distance in meters along the surface of the Earth.

Return type:

float

nereus.core.coordinates.great_circle_distance(lon1, lat1, lon2, lat2, radius=6371000.0)[source]

Compute great-circle distance between two points using Haversine formula.

Parameters:
  • lon1 (array_like) – Longitude and latitude of first point(s) in degrees.

  • lat1 (array_like) – Longitude and latitude of first point(s) in degrees.

  • lon2 (array_like) – Longitude and latitude of second point(s) in degrees.

  • lat2 (array_like) – Longitude and latitude of second point(s) in degrees.

  • radius (float, optional) – Earth radius in meters. Default is 6,371,000 m.

Returns:

Distance in meters.

Return type:

ndarray

nereus.core.coordinates.great_circle_path(start_lon, start_lat, end_lon, end_lat, n_points=100)[source]

Generate points along a great circle path.

Parameters:
  • start_lon (float) – Start point in degrees.

  • start_lat (float) – Start point in degrees.

  • end_lon (float) – End point in degrees.

  • end_lat (float) – End point in degrees.

  • n_points (int, optional) – Number of points along the path. Default is 100.

Returns:

lon, lat – Coordinates of points along the great circle path.

Return type:

tuple of ndarrays

nereus.core.coordinates.compute_element_centers(lon, lat, triangles)[source]

Compute element center coordinates, handling cyclic triangles.

For triangular meshes, computes the center of each triangle. Handles triangles that cross the dateline (±180°) by shifting longitudes before averaging.

Parameters:
  • lon (array_like) – Longitude coordinates of mesh nodes in degrees.

  • lat (array_like) – Latitude coordinates of mesh nodes in degrees.

  • triangles (array_like) – Triangle connectivity array of shape (3, nelem) or (nelem, 3). Contains indices into lon/lat arrays.

Returns:

lon_elem, lat_elem – Longitude and latitude of element centers.

Return type:

tuple of ndarrays

Examples

>>> lon_elem, lat_elem = compute_element_centers(mesh.lon, mesh.lat, mesh.face_nodes)

Constants

  • EARTH_RADIUS: Earth’s mean radius in meters (WGS84): 6_371_000.0

Grid Functions

Grid utilities for nereus.

Functions for creating regular grids for regridding and plotting.

nereus.core.grids.extract_coordinates(data)[source]

Extract longitude and latitude coordinates from an xarray DataArray.

This function attempts to automatically detect coordinate variables by looking for common naming conventions used in geophysical data.

Parameters:

data (xr.DataArray or array_like) – The data array to extract coordinates from. If not an xarray DataArray, returns (None, None).

Returns:

  • lon (ndarray or None) – Longitude coordinates if found, None otherwise.

  • lat (ndarray or None) – Latitude coordinates if found, None otherwise.

Return type:

tuple[NDArray | None, NDArray | None]

Notes

The function looks for coordinates with these common names:

Longitude: lon, longitude, x, nav_lon, glon, xt_ocean, xu_ocean, xh, xq, nod2d_lon Latitude: lat, latitude, y, nav_lat, glat, yt_ocean, yu_ocean, yh, yq, nod2d_lat

Examples

>>> import xarray as xr
>>> data = xr.DataArray(
...     np.random.rand(10, 20),
...     coords={"lat": np.arange(10), "lon": np.arange(20)},
...     dims=["lat", "lon"]
... )
>>> lon, lat = extract_coordinates(data)
>>> lon.shape, lat.shape
((20,), (10,))
nereus.core.grids.prepare_input_arrays(data, lon, lat)[source]

Prepare and validate input arrays, converting to 1D if necessary.

This function handles various input formats and transforms them to 1D arrays suitable for plotting and regridding. It issues warnings when transformations are applied.

Parameters:
  • data (array_like) – Data values, can be 1D or 2D.

  • lon (array_like) – Longitude coordinates, can be 1D or 2D.

  • lat (array_like) – Latitude coordinates, can be 1D or 2D.

Returns:

  • data_1d (ndarray) – 1D array of data values.

  • lon_1d (ndarray) – 1D array of longitude coordinates.

  • lat_1d (ndarray) – 1D array of latitude coordinates.

Raises:

ValueError – If array dimensions are incompatible or sizes don’t match.

Return type:

tuple[NDArray, NDArray[np.floating], NDArray[np.floating]]

Notes

Supported input combinations:

  • All 1D arrays of same size: used directly (no warning)

  • 2D data with 2D lon/lat (same shape): all raveled to 1D

  • 1D data with 2D lon/lat: lon/lat raveled to match data

  • 2D data with 1D lon/lat: meshgrid created, then all raveled

Examples

>>> # 2D data with 1D coordinates (regular grid)
>>> data = np.random.rand(180, 360)
>>> lon = np.linspace(-179.5, 179.5, 360)
>>> lat = np.linspace(-89.5, 89.5, 180)
>>> data_1d, lon_1d, lat_1d = prepare_input_arrays(data, lon, lat)
>>> data_1d.shape
(64800,)
nereus.core.grids.prepare_coordinates(lon, lat, data_shape=None)[source]

Prepare and validate coordinate arrays, converting to 1D if necessary.

This function handles various coordinate formats and transforms them to 1D arrays. It issues warnings when transformations are applied.

Parameters:
  • lon (array_like) – Longitude coordinates, can be 1D or 2D.

  • lat (array_like) – Latitude coordinates, can be 1D or 2D.

  • data_shape (tuple of int, optional) – Expected data shape for validation. If provided with 1D lon/lat, used to create a meshgrid matching the data dimensions.

Returns:

  • lon_1d (ndarray) – 1D array of longitude coordinates.

  • lat_1d (ndarray) – 1D array of latitude coordinates.

Raises:

ValueError – If array dimensions are incompatible or sizes don’t match.

Return type:

tuple[ndarray[tuple[Any, …], dtype[floating]], ndarray[tuple[Any, …], dtype[floating]]]

Examples

>>> # 2D coordinates
>>> lon_2d, lat_2d = np.meshgrid(np.arange(10), np.arange(5))
>>> lon_1d, lat_1d = prepare_coordinates(lon_2d, lat_2d)
>>> lon_1d.shape
(50,)
>>> # 1D coordinates with data shape
>>> lon = np.arange(10)
>>> lat = np.arange(5)
>>> lon_1d, lat_1d = prepare_coordinates(lon, lat, data_shape=(5, 10))
>>> lon_1d.shape
(50,)
nereus.core.grids.flatten_spatial(data)[source]

Flatten the last two spatial dimensions of an array into one.

Reshapes (..., nlat, nlon) to (..., npoints) where npoints = nlat * nlon. Works with both NumPy and dask arrays.

Parameters:

data (array_like) – Array with at least 2 dimensions.

Returns:

Reshaped array with the last two dimensions merged.

Return type:

array_like

Raises:

ValueError – If data has fewer than 2 dimensions.

nereus.core.grids.create_regular_grid(resolution=1.0, lon_bounds=(-180.0, 180.0), lat_bounds=(-90.0, 90.0), center='cell')[source]

Create a regular lon/lat grid.

Parameters:
  • resolution (float or tuple of int) – Grid resolution. If float, specifies degrees per grid cell. If tuple (nlon, nlat), specifies number of grid points.

  • lon_bounds (tuple of float) – Longitude bounds (lon_min, lon_max) in degrees.

  • lat_bounds (tuple of float) – Latitude bounds (lat_min, lat_max) in degrees.

  • center ({"cell", "node"}) – Whether coordinates are at cell centers or nodes. “cell” means coordinates at center of grid boxes. “node” means coordinates at corners.

Returns:

lon, lat – 2D arrays of longitude and latitude coordinates.

Return type:

tuple of ndarrays

Examples

>>> lon, lat = create_regular_grid(1.0)  # 1 degree resolution
>>> lon.shape
(180, 360)
>>> lon, lat = create_regular_grid((360, 180))  # 360x180 grid
>>> lon.shape
(180, 360)
nereus.core.grids.grid_cell_area(lon, lat, radius=6371000.0)[source]

Compute area of regular grid cells.

Parameters:
  • lon (ndarray) – 2D array of longitude coordinates (cell centers).

  • lat (ndarray) – 2D array of latitude coordinates (cell centers).

  • radius (float) – Earth radius in meters.

Returns:

2D array of cell areas in square meters.

Return type:

ndarray

Notes

Assumes uniform spacing in lon and lat. Area of a spherical rectangle: A = R^2 * |sin(lat1) - sin(lat2)| * |lon2 - lon1|

nereus.core.grids.expand_bounds_for_polar(lon_bounds, lat_bounds, factor=1.414)[source]

Expand bounding box for polar projections.

Polar projections need a larger data extent to fill the circular plot area without gaps.

Parameters:
  • lon_bounds (tuple of float) – Original longitude bounds.

  • lat_bounds (tuple of float) – Original latitude bounds.

  • factor (float) – Expansion factor. Default is sqrt(2).

Returns:

lon_bounds, lat_bounds – Expanded bounds.

Return type:

tuple of tuples