Ejemplo n.º 1
0
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    array: xarray.DataArray = cube.get_array()
    array += 1000
    # Shape (#dates, #bands, #rows, #cols)
    array.loc[:, 'red'] += 10
    array.loc[:, 'nir'] += 100
    return XarrayDataCube(array)
Ejemplo n.º 2
0
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    inarr = cube.get_array()
    B4 = inarr.loc[:, 'bandzero']
    B8 = inarr.loc[:, 'bandone']
    ndvi = (B8 - B4) / (B8 + B4)
    ndvi = ndvi.expand_dims(dim='bands', axis=-3).assign_coords(bands=['ndvi'])
    return XarrayDataCube(ndvi)
Ejemplo n.º 3
0
def apply_hypercube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    from scipy.signal import savgol_filter

    array: xarray.DataArray = cube.get_array()
    filled = array.interpolate_na(dim='t')
    smoothed_array = savgol_filter(filled.values, 5, 2, axis=0)
    return XarrayDataCube(xarray.DataArray(smoothed_array, dims=array.dims, coords=array.coords))
Ejemplo n.º 4
0
def hyper_min_median_max(udf_data: UdfData):
    """Compute the min, median and max of the time dimension of a hyper cube

    Hypercubes with time dimensions are required. The min, median and max reduction of th time axis will be applied
    to all hypercube dimensions.

    Args:
        udf_data (UdfData): The UDF data object that contains raster and vector tiles as well as hypercubes
        and structured data.

    Returns:
        This function will not return anything, the UdfData object "udf_data" must be used to store the resulting
        data.

    """
    # Iterate over each tile
    cube_list = []
    for cube in udf_data.get_datacube_list():
        min = cube.array.min(dim="t")
        median = cube.array.median(dim="t")
        max = cube.array.max(dim="t")

        min.name = cube.id + "_min"
        median.name = cube.id + "_median"
        max.name = cube.id + "_max"

        cube_list.append(XarrayDataCube(array=min))
        cube_list.append(XarrayDataCube(array=median))
        cube_list.append(XarrayDataCube(array=max))

    udf_data.set_datacube_list(cube_list)
Ejemplo n.º 5
0
def test_xarraydatacube_to_dict():
    array = xarray.DataArray(
        numpy.zeros(shape=(2, 3)),
        coords={
            'x': [1, 2],
            'y': [1, 2, 3]
        },
        dims=('x', 'y'),
        name="testdata",
        attrs={"description": "This is an xarray with two dimensions"},
    )
    xdc = XarrayDataCube(array=array)
    assert xdc.to_dict() == {
        "id":
        "testdata",
        "description":
        'This is an xarray with two dimensions',
        "data": [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]],
        "dimensions": [
            {
                'name': 'x',
                'coordinates': [1, 2]
            },
            {
                'name': 'y',
                'coordinates': [1, 2, 3]
            },
        ],
    }
Ejemplo n.º 6
0
def test_xarraydatacube_to_dict_minimal():
    array = xarray.DataArray(numpy.zeros(shape=(2, 3)))
    xdc = XarrayDataCube(array=array)
    assert xdc.to_dict() == {
        "data": [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]],
        "dimensions": [{
            "name": "dim_0"
        }, {
            "name": "dim_1"
        }],
    }
Ejemplo n.º 7
0
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    """Compute the NDVI based on sentinel2 tiles"""
    array: xarray.DataArray = cube.get_array()
    red = array.sel(bands="TOC-B04_10M")
    nir = array.sel(bands="TOC-B08_10M")
    ndvi = (nir - red) / (nir + red)

    import os
    statinfo = os.stat("/data/users/Public")
    print(statinfo)
    return XarrayDataCube(ndvi)
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    """
    Apply Savitzky-Golay smoothing to a timeseries datacube.
    This UDF preserves dimensionality, and assumes an input
    datacube with a temporal dimension 't' as input.
    """
    array: xarray.DataArray = cube.get_array()
    filled = array.interpolate_na(dim='t')
    smoothed_array = savgol_filter(filled.values, 5, 2, axis=0)
    return XarrayDataCube(array=xarray.DataArray(
        smoothed_array, dims=array.dims, coords=array.coords))
Ejemplo n.º 9
0
def test_save_load_guess_format_invalid(tmp_path):
    xdc = _build_xdc(ts=[2019, 2020, 2021],
                     bands=["a", "b"],
                     xs=[2, 3, 4, 5],
                     ys=[5, 6, 7, 8, 9])
    assert xdc.array.shape == (3, 2, 4, 5)
    path = tmp_path / "cube.foobar"
    with pytest.raises(ValueError, match="Can not guess format"):
        xdc.save_to_file(path)
    xdc.save_to_file(path, fmt="netcdf")
    with pytest.raises(ValueError, match="Can not guess format"):
        result = XarrayDataCube.from_file(path)
    result = XarrayDataCube.from_file(path, fmt="netcdf")
    xarray.testing.assert_equal(xdc.array, result.array)
Ejemplo n.º 10
0
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    # access the underlying xarray
    inarr=cube.get_array()

    # ndvi
    B4=inarr.loc[:,'B04']
    B8=inarr.loc[:,'B08']
    ndvi=(B8-B4)/(B8+B4)
    
    # extend bands dim
    ndvi=ndvi.expand_dims(dim='bands', axis=-3).assign_coords(bands=['ndvi'])
    
    # wrap back to datacube and return
    return XarrayDataCube(ndvi)
Ejemplo n.º 11
0
def test_datacube_list():
    xa = xarray.DataArray(numpy.zeros((2, 3)),
                          coords={
                              "x": [1, 2],
                              "y": [3, 4, 5]
                          },
                          dims=("x", "y"),
                          name="testdata")
    cube = XarrayDataCube(xa)
    udf_data = UdfData(datacube_list=[cube], user_context={"kernel": 3})
    assert udf_data.to_dict() == {
        "datacubes": [{
            "id":
            "testdata",
            "data": [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]],
            "dimensions": [{
                "name": "x",
                "coordinates": [1, 2]
            }, {
                "name": "y",
                "coordinates": [3, 4, 5]
            }],
        }],
        "feature_collection_list":
        None,
        "structured_data_list":
        None,
        "proj":
        None,
        "user_context": {
            "kernel": 3
        }
    }
    assert repr(udf_data) \
           == '<UdfData datacube_list:[<XarrayDataCube shape:(2, 3)>] feature_collection_list:None structured_data_list:None>'
Ejemplo n.º 12
0
def test_debug_udf_direct_invoke():
    """
    Shows how to run your UDF locally for testing, by invoking the function directly, breakpoints work.
    https://open-eo.github.io/openeo-python-client/udf.html#example-downloading-a-datacube-and-executing-an-udf-locally
    depends on composite.nc file created in earlier function!
    """
    from openeo.udf import XarrayDataCube
    udf_cube = XarrayDataCube.from_file('masked.nc', fmt='netcdf')

    apply_datacube(udf_cube,context={})
Ejemplo n.º 13
0
def test_save_load_guess_format(filename, save_format, load_format, tmp_path):
    xdc = _build_xdc(ts=[2019, 2020, 2021],
                     bands=["a", "b"],
                     xs=[2, 3, 4, 5],
                     ys=[5, 6, 7, 8, 9])
    assert xdc.array.shape == (3, 2, 4, 5)
    path = tmp_path / filename
    xdc.save_to_file(path, fmt=save_format)
    result = XarrayDataCube.from_file(path, fmt=load_format)
    xarray.testing.assert_equal(xdc.array, result.array)
Ejemplo n.º 14
0
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    """
    Applies a rolling window median composite to a timeseries datacube.
    This UDF preserves dimensionality, and assumes a datacube with a temporal dimension 't' as input.
    """

    array: xarray.DataArray = cube.get_array()

    #this method computes dekad's, can be used to resample data to desired frequency

    time_dimension_index = array.get_index('t')

    d = time_dimension_index.day - np.clip((time_dimension_index.day - 1) // 10, 0, 2) * 10 - 1
    date = time_dimension_index.values - np.array(d, dtype="timedelta64[D]")

    #replace each value with 30-day window median
    #first median rolling window to fill gaps on all dates
    composited = array.rolling(t=30,min_periods=1, center=True).median().dropna("t")
    #resample rolling window medians to dekads
    ten_daily_composite = composited.groupby_bins("t",date).median()
    return XarrayDataCube(ten_daily_composite)
Ejemplo n.º 15
0
def test_xarraydatacube_from_dict_minimal():
    d = {"data": [[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]]}
    xdc = XarrayDataCube.from_dict(d)
    assert isinstance(xdc, XarrayDataCube)
    assert xdc.id is None
    xarray.testing.assert_equal(
        xdc.get_array(), xarray.DataArray([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]]))
    assert xdc.to_dict() == {
        "data": [[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]],
        "dimensions": [{
            "name": "dim_0"
        }, {
            "name": "dim_1"
        }],
    }
Ejemplo n.º 16
0
def hyper_map_fabs(udf_data: UdfData):
    """Compute the absolute values of each hyper cube in the provided data

    Args:
        udf_data (UdfData): The UDF data object that contains raster and vector tiles as well as hypercubes
        and structured data.

    Returns:
        This function will not return anything, the UdfData object "udf_data" must be used to store the resulting
        data.

    """
    # Iterate over each tile
    cube_list = []
    for cube in udf_data.get_datacube_list():
        result = numpy.fabs(cube.array)
        result.name = cube.id + "_fabs"
        cube_list.append(XarrayDataCube(array=result))
    udf_data.set_datacube_list(cube_list)
Ejemplo n.º 17
0
def test_xarray_datacube_from_dict():
    d = {
        "id":
        "testdata",
        "description":
        'This is an xarray with two dimensions',
        "data": [[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]],
        "dimensions": [
            {
                'name': 'x',
                'coordinates': [1, 2]
            },
            {
                'name': 'y',
                'coordinates': [1, 2, 3]
            },
        ],
    }
    xdc = XarrayDataCube.from_dict(d)
    assert isinstance(xdc, XarrayDataCube)
    assert xdc.to_dict() == d
Ejemplo n.º 18
0
def _build_xdc(
    ts: Union[list, int] = None,
    bands: Union[list, int] = None,
    xs: Union[list, int] = None,
    ys: Union[list, int] = None,
    dtype=numpy.int32,
):
    """
    Build multi-dimensional XarrayDataCube containing given dimensions/coordinates
    """
    dims = []
    coords = {}
    value = numpy.zeros(shape=())
    for dim, cs in [("t", ts), ("bands", bands), ("x", xs), ("y", ys)]:
        if cs:
            dims.append(dim)
            if isinstance(cs, list):
                coords[dim] = cs
                cs = len(cs)
            value = 10 * value[..., None] + numpy.arange(cs)
    return XarrayDataCube(
        xarray.DataArray(value.astype(dtype), dims=dims, coords=coords))
Ejemplo n.º 19
0
def _build_txy_data(ts: list,
                    xs: list,
                    ys: list,
                    name: str,
                    offset=0,
                    t_factor=100,
                    x_factor=10,
                    y_factor=1) -> XarrayDataCube:
    """Build `XarrayDataCube` with given t, x and y labels"""
    t, x, y = numpy.ogrid[0:len(ts), 0:len(xs), 0:len(ys)]
    a = offset + t_factor * t + x_factor * x + y_factor * y
    return XarrayDataCube(
        xarray.DataArray(
            data=a,
            coords={
                "t": ts,
                "x": xs,
                "y": ys
            },
            dims=['t', 'x', 'y'],
            name=name,
        ))
Ejemplo n.º 20
0
def hyper_ndvi(udf_data: UdfData):
    """Compute the NDVI based on RED and NIR hypercubes

    Hypercubes with ids "red" and "nir" are required. The NDVI computation will be applied
    to all hypercube dimensions.

    Args:
        udf_data (UdfData): The UDF data object that contains raster and vector tiles as well as hypercubes
        and structured data.

    Returns:
        This function will not return anything, the UdfData object "udf_data" must be used to store the resulting
        data.

    """
    red = None
    nir = None

    # Iterate over each tile
    for cube in udf_data.get_datacube_list():
        if "red" in cube.id.lower():
            red = cube
        if "nir" in cube.id.lower():
            nir = cube
    if red is None:
        raise Exception("Red hypercube is missing in input")
    if nir is None:
        raise Exception("Nir hypercube is missing in input")

    ndvi = (nir.array - red.array) / (nir.array + red.array)
    ndvi.name = "NDVI"

    hc = XarrayDataCube(array=ndvi)
    udf_data.set_datacube_list([
        hc,
    ])
Ejemplo n.º 21
0
def datacube_from_file(filename, fmt='netcdf') -> "XarrayDataCube":
    from openeo.udf.xarraydatacube import XarrayDataCube
    return XarrayDataCube.from_file(path=filename, fmt=fmt)
Ejemplo n.º 22
0
def _assert_equal_after_save_and_load(xdc, tmp_path, format) -> XarrayDataCube:
    path = tmp_path / ("cube." + format)
    xdc.save_to_file(path=path, fmt=format)
    result = XarrayDataCube.from_file(path=path, fmt=format)
    xarray.testing.assert_equal(xdc.array, result.array)
    return result
Ejemplo n.º 23
0
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
    array: xarray.DataArray = cube.get_array()
    array += 60
    return XarrayDataCube(array)