pycsa.core.utils

This module contains miscellaneous helper functions and classes

Functions

delaunay(grid, cell[, res_x, res_y, xmax, ...])

Generates an idealised Delaunay triangle

gen_art_terrain(shp[, seed, iters])

Generates an artificial terrain by diffusing random noise.

get_closest_idx(val, arr)

Return the index of the array element closest to a target value.

get_lat_lon_segments(lat_verts, lon_verts, ...)

Populates an empty cell object given the vertices and underlying topography.

get_size(obj[, seen])

Recursively finds size of objects

handle_latlon_expansion(clat_vertices, ...)

Outward-pad a cell's vertex bounding box, wrapping at the poles/dateline.

is_land(cell, simplex_lat, simplex_lon, topo)

Decide whether a triangular cell is predominantly land.

isosceles(grid, cell[, xmax, ymax, res, tri])

Populates a cell instance with an idealised triangle

latlon2m(arr, fix_pt, latlon)

Compute along-axis distances (in meters) from the first element.

pick_cell(lat_ref, lon_ref, grid[, radius])

pick an ICON grid cell given (lon,lat) coorindates

rad2deg(val)

Radians to degrees converter

rescale(arr[, rng])

Rescales a list to the interval of [0,1]

sliding_window_view(arr, window_shape, steps)

Produce a view from a sliding, striding window over arr.

transfer_attributes(params, cls[, prefix])

Copy attributes from one object onto another, filling only the gaps.

Classes

gen_triangle(vx, vy[, x_rng, y_rng])

Defines a triangle generator given the coordinates of its vertices

taper(cell, padding[, stencil_typ, ...])

Helper class to apply tapering via artificial diffusion

pycsa.core.utils.pick_cell(lat_ref, lon_ref, grid, radius=1.0)

pick an ICON grid cell given (lon,lat) coorindates

Parameters:
  • lat_ref (float) – reference latitude coordinate in the cell to be picked

  • lon_ref (float) – reference longitude coordinate in the cell to be picked

  • grid (pycsa.data.cell.grid) – instance of an ICON grid

  • radius (float, optional) – radius from (lon_ref, lat_ref) to search for (clon,clat), by default 1.0

Returns:

index of the picked grid cell (the cell center closest to the reference location) into the grid’s clat/clon arrays.

Return type:

int

pycsa.core.utils.rad2deg(val)

Radians to degrees converter

Parameters:

val (float) – argument in units of radians

Returns:

argument in units of degrees

Return type:

float

pycsa.core.utils.isosceles(grid, cell, xmax=6.283185307179586, ymax=6.283185307179586, res=480, tri='mid')

Populates a cell instance with an idealised triangle

Parameters:
  • grid (pycsa.data.cell.grid) – instance of the grid class

  • cell (pycsa.data.cell.topo_cell) – instance of the cell class

  • xmax (float, optional) – first horizontal extent, by default 2.0*np.pi

  • ymax (float, optional) – second horizontal extent, by default 2.0*np.pi

  • res (int, optional) – resolution of the triangle, by default 480

  • tri (str, optional) – mid generates an isosceles triangle, left generates a lower and right an upper triangle. By default ‘mid’

Returns:

always returns 0, as this function generates only one triangle at index 0.

Return type:

int

pycsa.core.utils.delaunay(grid, cell, res_x=480, res_y=480, xmax=6.283185307179586, ymax=6.283185307179586, tri='lower')

Generates an idealised Delaunay triangle

Parameters:
  • grid (pycsa.data.cell.grid) – instance of the grid class

  • cell (pycsa.data.cell.topo_cell) – instance of the cell class

  • res_x (int, optional) – resolution of the first horizontal extent, by default 480

  • res_y (int, optional) – resolution of the second horizontal extent, by default 480

  • xmax (float, optional) – first horizontal extent, by default 2.0*np.pi

  • ymax (float, optional) – second horizontal extent, by default 2.0*np.pi

  • tri (str, optional) – lower generates a lower triangle, and upper an upper triangle. By default ‘lower’

Returns:

always returns 0, as this function generates only one triangle at index 0.

Return type:

int

pycsa.core.utils.gen_art_terrain(shp, seed=555, iters=1000)

Generates an artificial terrain by diffusing random noise.

A field of uniform random values of shape shp is smoothed by iters explicit diffusion steps (with periodic/wrap padding), then demeaned and rescaled so its peak-to-peak amplitude maps onto [-1, 1].

Deprecated since version 0.90.0.

Note

superceded by the idealised-test run scripts.

Parameters:
  • shp (tuple of int) – Shape (ny, nx) of the artificial terrain field to generate.

  • seed (int, optional) – Seed for the NumPy random generator, by default 555.

  • iters (int, optional) – Number of explicit diffusion iterations to apply, by default 1000.

Returns:

The generated 2-D terrain field, demeaned and rescaled so that its peak-to-peak range spans [-1, 1].

Return type:

ndarray

class pycsa.core.utils.gen_triangle(vx, vy, x_rng=None, y_rng=None)

Defines a triangle generator given the coordinates of its vertices

__init__(vx, vy, x_rng=None, y_rng=None)

Defines the triangle’s properties

Parameters:
  • vx (list) – [x1, x2, x3], list of the first coordinate of the vertices

  • vy (list) – [y1, y2, y3], list of the second coordinate of the vertices

  • x_rng (list, optional) – [x_min, x_max]: the full first horizontal extent of the domain encompassing the triangle, by default None

  • y_rng (list, optional) – [y_min, y_max]: the full second horizontal extent of the domain encompassing the triangle, by default None

  • note: (..) – x_rng and y_rng are required if the triangle does not span the full extent of the grid cell.:

pycsa.core.utils.rescale(arr, rng=None)

Rescales a list to the interval of [0,1]

Parameters:
  • arr (list) – data points to be rescaled

  • rng (list, optional) – extent to be rescaled, by default None

Returns:

  • listarr values rescaled to [0,1]

  • Note

    This rescaling is required to work with the fast point-in-triangle test of pycsa.core.utils.gen_triangle, whose name-mangled __is_inside_sm is exposed through the vectorised vec_get_mask attribute.

pycsa.core.utils.get_size(obj, seen=None)

Recursively finds size of objects

Note

Function taken from https://github.com/bosswissam/pysize. Useful in checking how much memory is required by the data objects generated by pycsa.data.cell.

pycsa.core.utils.get_lat_lon_segments(lat_verts, lon_verts, cell, topo, rect=False, filtered=True, padding=0, topo_mask=None, mask=None, load_topo=False, use_center=True)

Populates an empty cell object given the vertices and underlying topography.

Parameters:
  • lat_verts (list) – vertices of the cell in the first horizontal direction

  • lon_verts (list) – vertices of the cell in the second horizontal direction

  • cell (pycsa.data.cell.topo_cell) – instance of the cell object class

  • topo (pycsa.data.cell.topo) – instance of the topography object class

  • rect (bool, optional) – do the vertices describe a quadrilateral grid cell? By default False

  • filtered (bool, optional) – removes topographic features smaller than 5km in scale, by default True

  • padding (int, optional) – number of data points in the padded region, by default 0

  • topo_mask (array-like, optional) – tapering mask, by default None

  • mask (array-like, optional) – 2D Boolean mask to select for data points inside the non-quadrilateral grid cell, by default None

  • load_topo (bool, optional) – explicitly replaces the topography attribute in the cell cell.topo with the data given in topo, by default False

  • use_center (bool, optional) – If True (default), use center of domain as projection origin (minimizes distortion) If False, use corner of domain as projection origin (OLD behavior for testing)

pycsa.core.utils.get_closest_idx(val, arr)

Return the index of the array element closest to a target value.

Parameters:
  • val (float) – Target value to match against.

  • arr (array-like) – 1-D array to search.

Returns:

Index into arr of the element with the smallest absolute difference from val.

Return type:

int

pycsa.core.utils.latlon2m(arr, fix_pt, latlon)

Compute along-axis distances (in meters) from the first element.

Parameters:
  • arr (array-like) – 1D list/array of coordinates in degrees (latitudes if latlon='lat', longitudes if latlon='lon')

  • fix_pt (float) – Fixed coordinate in degrees: - for latlon='lat': the fixed longitude at which meridional distances are evaluated - for latlon='lon': the fixed latitude at which zonal (small-circle) distances are evaluated

  • latlon ({"lat", "lon"}) – Which axis the distances are computed along.

Returns:

Cumulative distances in meters starting at 0, monotonically non-decreasing.

Return type:

numpy.ndarray

Raises:

ValueError – If latlon is neither "lat" nor "lon".

pycsa.core.utils.sliding_window_view(arr, window_shape, steps)

Produce a view from a sliding, striding window over arr. The window is only placed in ‘valid’ positions - no overlapping over the boundary.

Parameters:
  • arr (numpy.ndarray, shape=(...,[x, (...), z])) – The array to slide the window over.

  • window_shape (Sequence[int]) – The shape of the window to raster: [Wx, (…), Wz], determines the length of [x, (…), z]

  • steps (Sequence[int]) – The step size used when applying the window along the [x, (…), z] directions: [Sx, (…), Sz]

Return type:

view of arr, shape=([X, (…), Z], …, [Wx, (…), Wz]), where X = (x - Wx) // Sx + 1

Note

This function is taken from: https://gist.github.com/meowklaski/4bda7c86c6168f3557657d5fb0b5395a

In general, given:

out = sliding_window_view(arr,
                            window_shape=[Wx, (...), Wz],
                            steps=[Sx, (...), Sz])
out[ix, (...), iz] = arr[..., ix*Sx:ix*Sx+Wx,  (...), iz*Sz:iz*Sz+Wz]

Example

>>> import numpy as np
>>> x = np.arange(9).reshape(3,3)
>>> x
array([[0, 1, 2],
    [3, 4, 5],
    [6, 7, 8]])
>>> y = sliding_window_view(x, window_shape=(2, 2), steps=(1, 1))
>>> y
array([[[[0, 1],
        [3, 4]],
        [[1, 2],
        [4, 5]]],
    [[[3, 4],
        [6, 7]],
        [[4, 5],
        [7, 8]]]])
>>> np.shares_memory(x, y)
    True
# Performing a neural net style 2D conv (correlation)
# placing a 4x4 filter with stride-1
>>> data = np.random.rand(10, 3, 16, 16)  # (N, C, H, W)
>>> filters = np.random.rand(5, 3, 4, 4)  # (F, C, Hf, Wf)
>>> windowed_data = sliding_window_view(data,
...                                     window_shape=(4, 4),
...                                     steps=(1, 1))
>>> conv_out = np.tensordot(filters,
...                         windowed_data,
...                         axes=[[1,2,3], [3,4,5]])
# (F, H', W', N) -> (N, F, H', W')
>>> conv_out = conv_out.transpose([3,0,1,2])
class pycsa.core.utils.taper(cell, padding, stencil_typ='OP', scale_fac=1.0, art_dt=0.5, art_it=800)

Helper class to apply tapering via artificial diffusion

__init__(cell, padding, stencil_typ='OP', scale_fac=1.0, art_dt=0.5, art_it=800)

Initializes an artificial diffusion scenario

Parameters:
  • cell (pycsa.data.cell.topo_cell) – instance of the cell object class

  • padding (int) – number of data points in the padded region

  • stencil_typ (str, optional) – Laplacian stencil choice, by default ‘OP’ which is also the most stable

  • scale_fac (float, optional) – scaling factor for the stencil, by default 1.0

  • art_dt (float, optional) – artificial diffusion time-step size, by default 0.5

  • art_it (int, optional) – number of iterations for the artificial discussion, by default 800

do_tapering()

Get tapered mask via artificial diffusion

pycsa.core.utils.transfer_attributes(params, cls, prefix='')

Copy attributes from one object onto another, filling only the gaps.

Iterates over the instance attributes of cls and writes each onto params only when the corresponding attribute is missing or currently None on params (existing non-None values are preserved). An optional prefix is prepended to each attribute name as "{prefix}_{key}" so that several source objects can be merged into a single namespace without clashing.

Parameters:
  • params (object) – Target object (e.g. a pycsa.config.params.params instance) that receives the attributes. Modified in place.

  • cls (object) – Source object whose instance attributes (via vars()) are copied.

  • prefix (str, optional) – Prefix prepended to each copied attribute name, by default "" (no prefix).

Returns:

params is mutated in place.

Return type:

None

pycsa.core.utils.is_land(cell, simplex_lat, simplex_lon, topo, height_tol=0.5, percent_tol=0.95)

Decide whether a triangular cell is predominantly land.

Loads the topography for the simplex into cell (via get_lat_lon_segments() with load_topo=True), then classifies the cell as land unless it is overwhelmingly at-or-below sea level. The cell is considered ocean (returns False) when the fraction of points with elevation <= height_tol exceeds percent_tol.

Parameters:
  • cell (pycsa.data.cell.topo_cell) – Cell instance; its topo field is populated as a side effect.

  • simplex_lat (array-like) – Latitude vertices of the triangular cell.

  • simplex_lon (array-like) – Longitude vertices of the triangular cell.

  • topo (pycsa.data.cell.topo) – Source topography object passed through to get_lat_lon_segments().

  • height_tol (float, optional) – Elevation threshold (in the topography’s units) below which a point is treated as sea/near-sea-level, by default 0.5.

  • percent_tol (float, optional) – Fraction of below-threshold points above which the cell is classed as ocean, by default 0.95.

Returns:

True if the cell is predominantly land, False if it is predominantly ocean.

Return type:

bool

pycsa.core.utils.handle_latlon_expansion(clat_vertices, clon_vertices, lat_expand=1.0, lon_expand=1.0)

Outward-pad a cell’s vertex bounding box, wrapping at the poles/dateline.

Rounds the vertex coordinates to 5 decimals, normalizes ambiguous ±180 longitudes so the extremes share a consistent sign, then pushes the extreme vertices outward: the max latitude/longitude vertex is grown by lat_expand/lon_expand and the min vertex shrunk by the same amount. Longitudes that fall outside [-180, 180] are wrapped by ±360°, and latitudes that overshoot ±90 are pulled back by the expansion amount.

Parameters:
  • clat_vertices (numpy.ndarray) – Latitude vertices of the cell (modified/returned).

  • clon_vertices (numpy.ndarray) – Longitude vertices of the cell (modified/returned).

  • lat_expand (float, optional) – Degrees by which to expand the latitude extent outward, by default 1.0.

  • lon_expand (float, optional) – Degrees by which to expand the longitude extent outward, by default 1.0.

Returns:

  • clat_vertices (numpy.ndarray) – Expanded latitude vertices, clamped/wrapped at the poles.

  • clon_vertices (numpy.ndarray) – Expanded longitude vertices, wrapped into [-180, 180].