11import operator
2+
3+ from collections .abc import Callable , Iterable , Mapping
24from typing import Tuple
3- import openeo
5+
46import numpy as np
7+ import openeo
58import scipy
6- from collections .abc import Callable , Mapping , Iterable
79
810
911def connect ():
1012 return openeo .connect ("https://openeo.dataspace.copernicus.eu/" )
1113
1214
13-
1415class TestArea :
1516 # aoi_wkt = "POINT (-15.432283 15.402828)"
1617 directions = ["west" , "south" , "east" , "north" ]
@@ -27,7 +28,7 @@ def __init__(
2728 "Syn_Oa06_reflectance" ,
2829 "Syn_Oa08_reflectance" ,
2930 "Syn_Oa17_reflectance" ,
30- ],
31+ ],
3132 temporal_extent : Iterable [str ] = ["2022-06-01" , "2022-06-30" ],
3233 ) -> None :
3334 self .bbox = bbox
@@ -55,7 +56,12 @@ def get_s3_cube(self, connection):
5556def distance_to_clouds (
5657 cube : openeo .DataCube , tolerance_percentage = 0.05 , ratio = 30 , max_distance = 255
5758):
58- return _distance_to_clouds_udf (cube , tolerance_percentage = tolerance_percentage , ratio = ratio , max_distance = max_distance )
59+ return _distance_to_clouds_udf (
60+ cube ,
61+ tolerance_percentage = tolerance_percentage ,
62+ ratio = ratio ,
63+ max_distance = max_distance ,
64+ )
5965
6066
6167def _distance_to_clouds_kernel (
@@ -88,13 +94,15 @@ def _distance_to_clouds_udf(
8894
8995
9096def extract_mask (
91- cube : openeo .DataCube ,
92- mask_values : Mapping [str , Iterable [int ]],
93- * ,
94- operations : Mapping [Tuple [str , int ], Callable ],
95- ) -> openeo .DataCube :
97+ cube : openeo .DataCube ,
98+ mask_values : Mapping [str , Iterable [int ]],
99+ * ,
100+ operations : Mapping [Tuple [str , int ], Callable ],
101+ ) -> openeo .DataCube :
96102 """
97- Generic method to extract a mask from a data cube.
103+ Generic method to extract a mask from exclusive classification bands.
104+ To extract a mask from a band that encodes classifications as bits
105+ (i.e. no-exclusive) use ``extract_bit_mask``.
98106 Generate a mask that has a value of ``True`` whereever the band specified
99107 as a key in ``mask_values`` is equal to one of the values speicified
100108 as a value. Operations other than equality comparison can be specified
@@ -121,10 +129,10 @@ def extract_mask(
121129 :param mask_values: Mapping of band names to the values that should be masked.
122130 :param operations: Used to specify a comparison operation different to ``==``
123131 when comparing bands and values. Operations are applied as ``op(band, value)``
124-
132+
125133 """
134+ assert len (mask_values ) > 0 , "'mask_values' cannot be empty."
126135
127- assert (len (mask_values ) > 0 ), "'mask_values' cannot be empty."
128136 def reduce_single_band (band_name , values_to_mask , mask = None ):
129137 band = cube .band (band_name )
130138 vm_iter = iter (values_to_mask )
@@ -148,3 +156,32 @@ def reduce_single_band(band_name, values_to_mask, mask=None):
148156 mask |= reduce_single_band (band_name , values_to_mask , mask )
149157
150158 return mask
159+
160+
161+ # TODO currently broken implmentation
162+ def _extract_bit_mask (
163+ cube : openeo .DataCube ,
164+ mask_bits : Mapping [str , int ],
165+ invert : bool = False ,
166+ ) -> openeo .DataCube :
167+ comparison_val = not invert
168+ assert len (mask_bits ) > 0 , "'mask_bits' cannot be empty."
169+
170+ def reduce_single_band (band_name , single_pixel_mask , mask = None ):
171+ band = cube .band (band_name )
172+
173+ if mask is None :
174+ mask = ((band & single_pixel_mask ) > 0 ) == comparison_val
175+ else :
176+ mask |= ((band & single_pixel_mask ) > 0 ) == comparison_val
177+ return mask
178+
179+ first_band_name , * bands = mask_bits .keys ()
180+ first_mask_bit , * bits_to_mask = mask_bits .values ()
181+
182+ mask = reduce_single_band (first_band_name , first_mask_bit , mask = None )
183+
184+ for band_name , bits_to_mask in zip (bands , bits_to_mask ):
185+ mask |= reduce_single_band (band_name , bits_to_mask , mask )
186+
187+ return mask
0 commit comments