Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make FlagBands aware of band aliases on the main product(s). #887

Merged
merged 8 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions datacube_ows/config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ class OWSFlagBandStandalone:
"""
def __init__(self, band: str) -> None:
self.pq_band = band
self.canonical_band_name = band
self.pq_names: List["datacube.model.DatasetType"] = []
self.pq_ignore_time = False
self.pq_manual_merge = False
Expand All @@ -649,7 +650,9 @@ def __init__(self, cfg: CFG_DICT, product_cfg: "datacube_ows.ows_configuration.O
pq_names = self.product.parse_pq_names(cfg)
self.pq_names = pq_names["pq_names"]
self.pq_low_res_names = pq_names["pq_low_res_names"]
self.main_products = pq_names["main_products"]
self.pq_band = cfg["band"]
self.canonical_band_name = self.pq_band # Update for aliasing on make_ready
if "fuse_func" in cfg:
self.pq_fuse_func: Optional[FunctionWrapper] = FunctionWrapper(self.product, cast(Mapping[str, Any], cfg["fuse_func"]))
else:
Expand Down Expand Up @@ -685,12 +688,19 @@ def make_ready(self, dc: "datacube.Datacube", *args, **kwargs) -> None:
raise ConfigException(f"Could not find flags low_res product {pqn} for layer {self.product.name} in datacube")
self.pq_low_res_products.append(pq_product)

# pyre-ignore[16]
# Resolve band alias if necessary.
if self.main_products:
try:
self.canonical_band_name = self.product.band_idx.band(self.pq_band)
except ConfigException:
pass

# pyre-ignore[16]
self.info_mask: int = ~0
# A (hopefully) representative product
product = self.pq_products[0]
try:
meas = product.lookup_measurements([self.pq_band])[self.pq_band]
meas = product.lookup_measurements([self.canonical_band_name])[self.canonical_band_name]
except KeyError:
raise ConfigException(
f"Band {self.pq_band} does not exist in product {product.name} - cannot be used as a flag band for layer {self.product.name}.")
Expand Down Expand Up @@ -723,7 +733,7 @@ def __init__(self, flag_band: FlagBand,
super().__init__({})
self.layer = layer
self.bands: Set[str] = set()
self.bands.add(flag_band.pq_band)
self.bands.add(flag_band.canonical_band_name)
self.flag_bands = {flag_band.pq_band: flag_band}
self.product_names = tuple(flag_band.pq_names)
self.ignore_time = flag_band.pq_ignore_time
Expand Down
12 changes: 11 additions & 1 deletion datacube_ows/ows_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,24 +921,30 @@ def parse_product_names(self, cfg):
raise ConfigException(f"'low_res_product_names' entry in non-multi-product layer {self.name} - use 'low_res_product_name' only")

def parse_pq_names(self, cfg):
main_product = False
if "dataset" in cfg:
raise ConfigException(f"The 'dataset' entry in the flags section is no longer supported. Please refer to the documentation for the correct format (layer {self.name})")
if "product" in cfg:
pq_names = (cfg["product"],)
else:
pq_names = (self.product_name,)
main_product = (pq_names[0] == self.product_name)

if "low_res_product" in cfg:
pq_low_res_names = (cfg.get("low_res_product"),)
else:
elif main_product:
pq_low_res_names = self.low_res_product_names
else:
pq_low_res_names = pq_names

if "products" in cfg:
raise ConfigException(f"'products' entry in flags section of non-multi-product layer {self.name} - use 'product' only")
if "low_res_products" in cfg:
raise ConfigException(f"'low_res_products' entry in flags section of non-multi-product layer {self.name}- use 'low_res_product' only")
return {
"pq_names": pq_names,
"pq_low_res_names": pq_low_res_names,
"main_products": main_product
}


Expand All @@ -959,11 +965,14 @@ def parse_product_names(self, cfg):
raise ConfigException(f"'low_res_product_name' entry in multi-product layer {self.name} - use 'low_res_product_names' only")

def parse_pq_names(self, cfg):
main_products = False
if "datasets" in cfg:
raise ConfigException(f"The 'datasets' entry in the flags section is no longer supported. Please refer to the documentation for the correct format (layer {self.name})")
if "products" in cfg:
pq_names = tuple(cfg["products"])
main_products = pq_names == self.product_names
else:
main_products = True
pq_names = self.product_names

if "low_res_products" in cfg:
Expand All @@ -977,6 +986,7 @@ def parse_pq_names(self, cfg):
return {
"pq_names": pq_names,
"pq_low_res_names": pq_low_res_names,
"main_products": main_products,
}

def dataset_groupby(self):
Expand Down
6 changes: 5 additions & 1 deletion docs/cfg_layers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1003,8 +1003,12 @@ The name of the measurement band to be used for style-based masking.
Pixel-quality bitmask bands or enumeration flag bands can be used, although
bitmask bands are better supported and are recommended where possible.

If the flag product(s) is/are the same as the main data product(s), then
an alias from the `bands dictionary <#bands-dictionary-bands>`_ may be used.

Note that it is not possible to combine flag bands from separate products
if they have the same band name.
if they have the same band name (unless one of the products is the main product
and a band alias is used.)

Required.

Expand Down
6 changes: 3 additions & 3 deletions integration_tests/cfg/ows_test_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@
"nbart_nir_2": ["nbar_nir_2", "nir2", "nbart_nir_2"],
"nbart_swir_2": ["nbar_swir_2", "swir_2", "nbart_swir_2"],
"nbart_swir_3": ["nbar_swir_3", "swir_3", "nbart_swir_3"],
"fmask": ["fmask"],
"fmask": ["fmask", "fmask_alias"],
}


# REUSABLE CONFIG FRAGMENTS - Style definitions

s2_nrt_fmask = [
{
"band": "fmask",
"band": "fmask_alias",
"values": [0, 2, 3],
"invert": True,
},
Expand Down Expand Up @@ -807,7 +807,7 @@
},
"flags": [
{
"band": "fmask",
"band": "fmask_alias",
"products": ["s2a_ard_granule", "s2b_ard_granule"],
"ignore_time": False,
"ignore_info_flags": []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Over-ridden: aardvark 2022-03-24T23:29:57.407805\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2022-08-26 13:23+1000\n"
"POT-Creation-Date: 2022-10-18 13:28+1100\n"
"PO-Revision-Date: 2022-03-24 23:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
Expand Down
1 change: 1 addition & 0 deletions tests/test_styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def __init__(self, pq_name, band):
self.pq_products = [FakeODCProduct(pq_name)]
self.pq_low_res_products = None
self.pq_band = band
self.canonical_band_name = band
self.pq_names = [pq_name]
self.pq_ignore_time = False
self.pq_manual_merge = False
Expand Down