'''
Created on Jun 26, 2017
@author: jfpiolle
'''
from collections import OrderedDict
# recommended cloud mask
DEFAULT_CLOUDMASK = [
'visible',
'1.37_threshold',
'1.6_large_histogram',
'2.25_large_histogram',
'gross_cloud',
'thin_cirrus',
'medium_high',
'11_12_view_difference',
'3.7_11_view_difference',
'fog_low_stratus',
'11_spatial_coherence',
]
WST_MASK = [
'gross_cloud',
'thin_cirrus',
'medium_high',
'fog_low_stratus',
'11_spatial_coherence',
'1.6_large_histogram',
'11_12_view_difference',
'3.7_11_view_difference',
'visible',
'2.25_large_histogram',
'1.37_threshold'
]
FLAGS = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768]
MEANINGS = ("visible 1.37_threshold 1.6_small_histogram 1.6_large_histogram "
"2.25_small_histogram 2.25_large_histogram 11_spatial_coherence "
"gross_cloud thin_cirrus medium_high fog_low_stratus "
"11_12_view_difference 3.7_11_view_difference thermal_histogram"
" spare spare").split()
[docs]def cloud_mask(
bitmask,
flagmeanings=MEANINGS,
flags=FLAGS,
bits=DEFAULT_CLOUDMASK):
"""Build the cloud mask from the bitmask variable and the positional bits.
Args:
bitmask (numpy.ndarray): the bitmask array (ex: content of
'cloud_in' variable)
flagmeanings (list): the list of flag meanings (explanation associated
with each flag value, as provided in flag_meanings CF attribute
flags (list): the list of flag values, as provided in flag_masks
CF attribute
bits (list, optional): list of bits to test for cloud mask extraction,
if you don't want to use default values (preset for
'S3A_SL_2_WCT__cloud_in' variable). The default flag selection is:
* 1.37_threshold
* gross_cloud
* thin_cirrus
* medium_high
* 11_12_view_difference
* 3.7_11_view_difference
* fog_low_stratus
* 11_spatial_coherence
Return:
numpy.ndarray: array of boolean (True when cloudy)
"""
allmeanings = flagmeanings
if not isinstance(allmeanings, list):
# split whitespace separated attribute items in a list
allmeanings = [_ for _ in allmeanings.split(' ') if _ != '']
# calculate sum (and) of all mask bits requested to be set
bitlist = bits
masksum = 0
for criterium in bitlist:
try:
bit = allmeanings.index(criterium)
except:
raise ValueError("Unknown flag meaning {}".format(criterium))
masksum += flags[bit]
# calculate mask
return (bitmask & masksum) > 0
[docs]def cloud_summary(
bitmask,
flagmeanings=MEANINGS,
flags=FLAGS,
bits=DEFAULT_CLOUDMASK):
"""Return the cloud summary, flag by flag
Args:
bitmask (numpy.ndarray): the bitmask array (ex: content of
'cloud_in' variable)
flagmeanings (list): the list of flag meanings (explanation associated
with each flag value, as provided in flag_meanings CF attribute
flags (list): the list of flag values, as provided in flag_masks
CF attribute
Return:
dict of numpy.ndarray: a dictionary of boolean arrays (True is set when
cloudy), one for each mask bit tested.
"""
cloud_mask_dict = OrderedDict([])
for flag in flagmeanings:
cloud_mask_dict[flag] = cloud_mask(
bitmask,
flagmeanings,
flags,
[flag]
)
return cloud_mask_dict