From a86b24b7b1428bf9c5c611eced9edc56c52c9a11 Mon Sep 17 00:00:00 2001 From: clausmichele Date: Wed, 23 Aug 2023 12:43:55 +0200 Subject: [PATCH 1/3] Draft for labelled arrays --- .../process_implementations/arrays.py | 15 ++++++++++++--- .../process_implementations/cubes/reduce.py | 7 ++++--- .../process_implementations/math.py | 6 +++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/openeo_processes_dask/process_implementations/arrays.py b/openeo_processes_dask/process_implementations/arrays.py index 3f8876e4..67986482 100644 --- a/openeo_processes_dask/process_implementations/arrays.py +++ b/openeo_processes_dask/process_implementations/arrays.py @@ -7,6 +7,7 @@ import pandas as pd import xarray as xr from numpy.typing import ArrayLike +from openeo_pg_parser_networkx.pg_schema import DateTime from xarray.core.duck_array_ops import isnull, notnull from openeo_processes_dask.process_implementations.cubes.utils import _is_dask_array @@ -42,6 +43,8 @@ def array_element( label: Optional[str] = None, return_nodata: Optional[bool] = False, axis=None, + context=None, + dim_labels=None, ): if index is None and label is None: raise ArrayElementParameterMissing( @@ -54,14 +57,20 @@ def array_element( ) if label is not None: - raise NotImplementedError( - "labelled arrays are currently not implemented. Please use index instead." - ) + if isinstance(label, DateTime): + label = label.to_numpy() + (index,) = np.where(dim_labels == label) + if len(index) == 0: + index = None + else: + index = index[0] try: if index is not None: element = np.take(data, index, axis=axis) return element + else: + raise IndexError except IndexError: if return_nodata: logger.warning( diff --git a/openeo_processes_dask/process_implementations/cubes/reduce.py b/openeo_processes_dask/process_implementations/cubes/reduce.py index 0998fc81..44d13499 100644 --- a/openeo_processes_dask/process_implementations/cubes/reduce.py +++ b/openeo_processes_dask/process_implementations/cubes/reduce.py @@ -21,15 +21,16 @@ def reduce_dimension( f"Provided dimension ({dimension}) not found in data.dims: {data.dims}" ) - positional_parameters = {"data": 0} - named_parameters = {"context": context} + dim_labels = data[dimension].values + positional_parameters = {"data": 0} reduced_data = data.reduce( reducer, dim=dimension, keep_attrs=True, positional_parameters=positional_parameters, - named_parameters=named_parameters, + context=context, + dim_labels=dim_labels, ) # Preset diff --git a/openeo_processes_dask/process_implementations/math.py b/openeo_processes_dask/process_implementations/math.py index 2888b285..525d4a0e 100644 --- a/openeo_processes_dask/process_implementations/math.py +++ b/openeo_processes_dask/process_implementations/math.py @@ -85,12 +85,12 @@ def constant(x): return x -def divide(x, y): +def divide(x, y, **kwargs): result = x / y return result -def subtract(x, y): +def subtract(x, y, **kwargs): result = x - y return result @@ -100,7 +100,7 @@ def multiply(x, y): return result -def add(x, y): +def add(x, y, **kwargs): result = x + y return result From af9b288a2009c6154c1d220204e0ed733a7ada18 Mon Sep 17 00:00:00 2001 From: clausmichele Date: Fri, 29 Sep 2023 15:31:45 +0200 Subject: [PATCH 2/3] Logic update --- openeo_processes_dask/process_implementations/core.py | 8 +++++++- openeo_processes_dask/process_implementations/math.py | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/openeo_processes_dask/process_implementations/core.py b/openeo_processes_dask/process_implementations/core.py index 1d78ec85..9d543990 100644 --- a/openeo_processes_dask/process_implementations/core.py +++ b/openeo_processes_dask/process_implementations/core.py @@ -68,7 +68,13 @@ def wrapper( else: resolved_kwargs[k] = arg - special_args = ["axis", "keepdims", "source_transposed_axis"] + special_args = [ + "axis", + "keepdims", + "source_transposed_axis", + "context", + "dim_labels", + ] # Remove 'axis' and keepdims parameter if not expected in function signature. for arg in special_args: if arg not in inspect.signature(f).parameters: diff --git a/openeo_processes_dask/process_implementations/math.py b/openeo_processes_dask/process_implementations/math.py index 525d4a0e..2888b285 100644 --- a/openeo_processes_dask/process_implementations/math.py +++ b/openeo_processes_dask/process_implementations/math.py @@ -85,12 +85,12 @@ def constant(x): return x -def divide(x, y, **kwargs): +def divide(x, y): result = x / y return result -def subtract(x, y, **kwargs): +def subtract(x, y): result = x - y return result @@ -100,7 +100,7 @@ def multiply(x, y): return result -def add(x, y, **kwargs): +def add(x, y): result = x + y return result From 596995a0697a64e0c2d6a10575d6ce6ea758874a Mon Sep 17 00:00:00 2001 From: clausmichele Date: Fri, 29 Sep 2023 15:43:41 +0200 Subject: [PATCH 3/3] Added label test --- tests/test_arrays.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_arrays.py b/tests/test_arrays.py index e052547f..ff68a484 100644 --- a/tests/test_arrays.py +++ b/tests/test_arrays.py @@ -48,6 +48,24 @@ def test_array_element( xr.testing.assert_equal(output_cube, input_cube.isel({"bands": 1}, drop=True)) + # Use a label + _process = partial( + process_registry["array_element"].implementation, + label="B02", + data=ParameterReference(from_parameter="data"), + ) + + output_cube = reduce_dimension(data=input_cube, reducer=_process, dimension="bands") + + general_output_checks( + input_cube=input_cube, + output_cube=output_cube, + verify_attrs=False, + verify_crs=True, + ) + + xr.testing.assert_equal(output_cube, input_cube.loc[{"bands": "B02"}].drop("bands")) + # When the index is out of range, we expect an ArrayElementNotAvailable exception to be thrown _process_not_available = partial( process_registry["array_element"].implementation,