Source code for eocrops.inputs.utils_sh

import eolearn
from eolearn.core import EOTask, FeatureType
from sentinelhub import SHConfig
import numpy as np
from eolearn.core import AddFeatureTask, RemoveFeatureTask


[docs]def config_sentinelhub_cred(api, client_id, client_secret): """ Configure properly Sentinelhub credential fetching information from the configuration tool python class. :return: SHConfig """ config = SHConfig() if client_id and client_secret and api: config.instance_id = api config.sh_client_id = client_id config.sh_client_secret = client_secret return config
[docs]def calculate_valid_data_mask(eopatch): """Define which pixel will be masked from eo-patch Inputs : - eopatch : patch downloaded from eo-learn packages (eopatch object with arrays) """ return np.logical_and( eopatch.mask["IS_DATA"].astype(np.bool), np.logical_not(eopatch.mask["CLM"].astype(np.bool)), )
[docs]def calculate_coverage(array): """Share of pixels not contaminated by clouds Inputs : - array : array from an eopatch object that contains information about cloud coverage (e.g Sentinel-2 L1C) """ return 1.0 - np.count_nonzero(array) / np.size(array)
[docs]class AddValidDataCoverage(EOTask): """Share of pixels not contaminated by clouds Inputs : - EOTask : workflow as EOTask object """ def execute(self, eopatch): valid_data = eopatch[eolearn.core.FeatureType.MASK]["VALID_DATA"] time, height, width, channels = valid_data.shape coverage = np.apply_along_axis( calculate_coverage, 1, valid_data.reshape((time, height * width * channels)) ) add_coverage = AddFeatureTask((eolearn.core.FeatureType.SCALAR, "COVERAGE")) return add_coverage.execute(eopatch=eopatch, data=coverage[:, np.newaxis])
[docs]class AddValidDataMaskTask(EOTask): def execute(self, eopatch): eopatch.mask["VALID_DATA"] = eopatch.mask["IS_DATA"].astype(bool) & ~( eopatch.mask["CLM"].astype(bool) ) return eopatch
[docs]class ValidDataS2(EOTask): """ The tasks recognize clouds from Sentinel Scene Layers (SCL) obtained from Sen2Corr """ def execute(self, eopatch): add_cloud = AddFeatureTask((eolearn.core.FeatureType.MASK, "VALID_DATA")) return add_cloud.execute( eopatch=eopatch, data=(eopatch.mask["IS_DATA"]).astype(bool) )
[docs]class ValidDataVHRS(EOTask): """ The tasks recognize clouds from Sentinel Scene Layers (SCL) obtained from Sen2Corr """ def execute(self, eopatch): cloud_mask_ = np.invert(eopatch[FeatureType.MASK]["CLM"].astype(bool)) add_bool = AddFeatureTask((eolearn.core.FeatureType.MASK, "IS_DATA")) add_bool.execute(eopatch=eopatch, data=np.invert(cloud_mask_)) add_cloud = AddFeatureTask((eolearn.core.FeatureType.MASK, "CLM")) add_cloud.execute(eopatch=eopatch, data=cloud_mask_) add_valid = AddFeatureTask((eolearn.core.FeatureType.MASK, "VALID_DATA")) add_valid.execute(eopatch=eopatch, data=np.invert(cloud_mask_)) return eopatch
[docs]class ValidPixel: def __call__(self, eopatch): return np.logical_and( eopatch.mask["IS_DATA"].astype(np.bool), np.logical_not(eopatch.mask["CLM"].astype(np.bool)), )
[docs]class CountValid(EOTask): """ The task counts number of valid observations in time-series and stores the results in the timeless mask. """ def __init__(self, count_what, feature_name): self.what = count_what self.name = feature_name def execute(self, eopatch): add_count = AddFeatureTask((eolearn.core.FeatureType.MASK_TIMELESS, self.name)) add_count.execute( eopatch=eopatch, data=np.count_nonzero(eopatch.mask[self.what], axis=0) ) return eopatch
[docs]class ValidDataCoveragePredicate: """ Keep an image only if below % of non contaminated pixels Inputs : - threshold (float) : upper bound of percentage of pixel predicted as cloudy """ def __init__(self, threshold): self.threshold = threshold def __call__(self, array): return calculate_coverage(array) < self.threshold
[docs]class EmptyTask(EOTask): """ This task does not make any change. It is just to avoid to duplicate the LinearWorflow with if/else For example, saving a EOPatch in the workflow would depend if the user specify a path in the parameters of the function workflow """ def __init__(self): self.Nothing = "Nothing" def execute(self, eopatch): return eopatch