<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 LinearWorkflow, FeatureType
from eolearn.io import SentinelHubInputTask
from eolearn.mask import AddValidDataMaskTask<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 ValidDataPredicate:
    def __call__(self, eopatch):
        return np.logical_and(eopatch.mask['dataMask'].astype(np.bool), 
                              np.logical_not(eopatch.mask['CLM'].astype(np.bool)))
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
)
add_valmask = AddValidDataMaskTask(predicate=ValidDataPredicate(), valid_data_feature='VALID_DATA')<jupyter_output><empty_output><jupyter_text>Run workflow<jupyter_code>workflow = LinearWorkflow(input_task, add_valmask)
result = workflow.execute({
    input_task: {
        'bbox': roi_bbox,
        'time_interval': time_interval
    }
})<jupyter_output><empty_output><jupyter_text>Plot results<jupyter_code>eopatch = result[add_valmask]

eopatch
# helper function
def plot_timestamp(eop, timestamp_idx):
    fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(20,12))
    ax[0][0].imshow(2.5 * eop.data['trueColorBands'][timestamp_idx][...,[2,1,0]])
    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.12609871534820824, 'fraction_numerical': 0.02738336713995943, 'mean_word_length': 5.865429234338747, 'pattern_counts': {'":': 0, '<': 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': '215596', 'license': 'MIT', 'n_tokens_mistral': 1068, 'n_tokens_neox': 1017, 'n_words': 224, 'path': 'examples/mask/ValidDataMask.ipynb', 'repo_name': 'asylve/eo-learn', 'size': '2958'}