Skip to content

Lifting geoops operators over cubes (xrops.lift)

geoops geometry operators (Reproject, Resample, Gradient2D, …) take their geometry from each item's grid, so they need a geoarray.GeoArray per item and refuse a DataArray. xrops.lift(op, dim=...) runs such an operator on every item of a cube along dim (geostack OP-O4): each item becomes a GeoArray (GeoArray.from_xarray, reading the CF spatial_ref), goes through the operator, and comes back with to_xarray.

import geoops.geom as gg
import xrops

# cube: DataArray["time band y x"] with a CF spatial_ref (geoarray's to_xarray layout)
reprojected = xrops.lift(gg.Reproject(dst_crs="EPSG:3857"), dim="time")(cube)
gradient = xrops.lift(gg.Gradient2D(nan_policy="adaptive"), dim="time")(cube)
#   DataArray["time band component y x"]

On a dask cube the lift is lazy, with one task per dim chunk; the output's grid comes from running the operator once on a zero-filled item, so building the graph computes nothing. Each item must be whole, so a cube chunked along any other dim raises and names the .chunk({...: -1}) that fixes it. The coordinate along dim (the time stamps) is carried through untouched.

lift

lift(op: Operator, *, dim: str) -> Lift

Apply a geoops geometry operator per item over an xarray cube.

Parameters:

Name Type Description Default
op Operator

A geoops operator on one GeoArray (geoops.geom.Reproject, Resample, Gradient2D, …).

required
dim str

The dim to iterate over; each item along it is one GeoArray.

required

Returns:

Type Description
Lift

An operator on a DataArray with a CF spatial_ref (geoarray's

Lift

to_xarray layout): dim first, then op's output dims, with

Lift

dim's coordinate carried through. Lazy on dask, one task per

Lift

dim chunk; the cube must be whole along every other dim.

Example

import numpy as np import xarray as xr from geoarray import GeoArray import geoops.geom as gg items = [ ... GeoArray(np.full((4, 5), float(t)), (1.0, 0, 0, 0, -1.0, 4.0), ... "EPSG:4326", dims=("y", "x")).to_xarray() ... for t in range(3) ... ] cube = xr.concat(items, dim="time").assign_coords(time=[0, 1, 2]) lift(gg.Gradient2D(), dim="time")(cube).dims ('time', 'component', 'y', 'x')

Source code in packages/xrtoolz-ops/src/xrops/_src/lift.py
def lift(op: _PipekitOperator, *, dim: str) -> Lift:
    """Apply a geoops geometry operator per item over an xarray cube.

    Args:
        op: A geoops operator on one ``GeoArray`` (``geoops.geom.Reproject``,
            ``Resample``, ``Gradient2D``, …).
        dim: The dim to iterate over; each item along it is one ``GeoArray``.

    Returns:
        An operator on a ``DataArray`` with a CF ``spatial_ref`` (geoarray's
        `to_xarray` layout): ``dim`` first, then ``op``'s output dims, with
        ``dim``'s coordinate carried through. Lazy on dask, one task per
        ``dim`` chunk; the cube must be whole along every other dim.

    Example:
        >>> import numpy as np
        >>> import xarray as xr
        >>> from geoarray import GeoArray
        >>> import geoops.geom as gg
        >>> items = [
        ...     GeoArray(np.full((4, 5), float(t)), (1.0, 0, 0, 0, -1.0, 4.0),
        ...              "EPSG:4326", dims=("y", "x")).to_xarray()
        ...     for t in range(3)
        ... ]
        >>> cube = xr.concat(items, dim="time").assign_coords(time=[0, 1, 2])
        >>> lift(gg.Gradient2D(), dim="time")(cube).dims
        ('time', 'component', 'y', 'x')
    """
    return Lift(op, dim=dim)

Lift

Lift(op: Operator, *, dim: str)

Bases: Operator

op applied to each item of a cube along dim; built by lift.

Parameters:

Name Type Description Default
op Operator

A geoops operator that takes and returns one GeoArray.

required
dim str

The dim whose items are run one at a time ("time").

required

Raises:

Type Description
ValueError

A dask cube is chunked along a dim other than dim (each item must be whole), or dim is not a dim of the cube.

Source code in packages/xrtoolz-ops/src/xrops/_src/lift.py
def __init__(self, op: _PipekitOperator, *, dim: str) -> None:
    self.op = op
    self.dim = dim