<jupyter_start><jupyter_text>Example of generation of valid data mask using a predicate Notebook showing an example of predicate for generation of valid data mask<jupyter_code>%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np
import datetime

from sentinelhub import BBox, CRS, DataCollection

from eolearn.core import EOTask, EOWorkflow, EONode, FeatureType, OutputTask
from eolearn.io import SentinelHubInputTask<jupyter_output><empty_output><jupyter_text>Define ROI BBOX and time interval<jupyter_code>roi_bbox = BBox(bbox=[12.14, 45.36, 12.55, 45.54], crs=CRS.WGS84)
time_interval = ("2020-06-01", "2020-06-23")<jupyter_output><empty_output><jupyter_text>Workflow to merge the cloud mask with the mask defining where reflectance data is available The predicate merges the cloud mask with the `dataMask` mask which defines where satellite data is available. For orbits covering partially the ROI, the mask values will be 0, as is shown in this example.<jupyter_code>class AddValidDataMaskTask(EOTask):
    def execute(self, eopatch):
        eopatch.mask["VALID_DATA"] = eopatch.mask["dataMask"].astype(bool) & ~(eopatch.mask["CLM"].astype(bool))
        return eopatch
input_task = SentinelHubInputTask(
    data_collection=DataCollection.SENTINEL2_L1C,
    bands=["B02", "B03", "B04"],
    bands_feature=(FeatureType.DATA, "trueColorBands"),
    additional_data=[(FeatureType.MASK, "dataMask"), (FeatureType.MASK, "CLM")],
    resolution=(160, 160),
    time_difference=datetime.timedelta(hours=2),
    max_threads=3,
)
input_node = EONode(input_task)

add_valmask_node = EONode(AddValidDataMaskTask(), inputs=[input_node])

output_node = EONode(OutputTask("final_eopatch"), inputs=[add_valmask_node])<jupyter_output><empty_output><jupyter_text>Run workflow<jupyter_code>workflow = EOWorkflow([input_node, add_valmask_node, output_node])

result = workflow.execute({input_node: {"bbox": roi_bbox, "time_interval": time_interval}})<jupyter_output><empty_output><jupyter_text>Plot results<jupyter_code>eopatch = result.outputs["final_eopatch"]

eopatch
# helper function
def plot_timestamp(eop, timestamp_idx):
    fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(20, 12))
    ax[0][0].imshow(np.clip(2.5 * eop.data["trueColorBands"][timestamp_idx][..., [2, 1, 0]], 0, 1))
    ax[0][0].set_title("True color image")

    ax[0][1].imshow(np.squeeze(eop.mask["VALID_DATA"][timestamp_idx]), cmap="gray")
    ax[0][1].set_title("VALID_DATA")

    ax[1][0].imshow(np.squeeze(eop.mask["dataMask"][timestamp_idx]), cmap="gray")
    ax[1][0].set_title("dataMask")

    ax[1][1].imshow(np.squeeze(eop.mask["CLM"][timestamp_idx]), cmap="gray")
    ax[1][1].set_title("CLM");
# In this case part of the image is outside 'orbit', and part is covered with (small) clouds. `VALID_DATA` is constructed from both.

plot_timestamp(eopatch, 5)
# In this case all pixels have valid data (dataMask==0), but there is a cloud, so `VALID_DATA` is a negate of `CLM` mask

plot_timestamp(eopatch, 6)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13304721030042918, 'fraction_numerical': 0.027401782766589635, 'mean_word_length': 6.593984962406015, 'pattern_counts': {'":': 2, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '55582', 'license': 'MIT', 'n_tokens_mistral': 1121, 'n_tokens_neox': 1063, 'n_words': 237, 'path': 'examples/mask/ValidDataMask.ipynb', 'repo_name': 'chorng/eo-learn', 'size': '3029'}