Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
colormap = self.build_colormap(palette, data.dtype, data.attrs)
channels, colors = colormap.palettize(np.asanyarray(data.squeeze()))
channels = palette[channels]
r = xr.DataArray(channels[:, :, 0].reshape(data.shape),
dims=data.dims, coords=data.coords)
g = xr.DataArray(channels[:, :, 1].reshape(data.shape),
dims=data.dims, coords=data.coords)
b = xr.DataArray(channels[:, :, 2].reshape(data.shape),
dims=data.dims, coords=data.coords)
return super(PaletteCompositor, self).__call__((r, g, b), **data.attrs)
class DayNightCompositor(GenericCompositor):
"""A compositor that takes one composite on the night side, another on day
side, and then blends them together."""
def __call__(self, projectables, lim_low=85., lim_high=95., *args,
**kwargs):
if len(projectables) != 3:
raise ValueError("Expected 3 datasets, got %d" %
(len(projectables), ))
try:
day_data = projectables[0].copy()
night_data = projectables[1].copy()
coszen = np.cos(np.deg2rad(projectables[2]))
coszen -= min(np.cos(np.deg2rad(lim_high)),
np.cos(np.deg2rad(lim_low)))
def __call__(self, datasets, optional_datasets=None, **attrs):
"""Generate the composite."""
colors = ['red', 'green', 'blue']
if self.high_resolution_band not in colors:
raise ValueError("SelfSharpenedRGB requires at least one high resolution band, not "
"'{}'".format(self.high_resolution_band))
high_res = datasets[colors.index(self.high_resolution_band)]
high_mean = self.four_element_average_dask(high_res)
red = high_mean if self.high_resolution_band == 'red' else datasets[0]
green = high_mean if self.high_resolution_band == 'green' else datasets[1]
blue = high_mean if self.high_resolution_band == 'blue' else datasets[2]
return super(SelfSharpenedRGB, self).__call__((red, green, blue), optional_datasets=(high_res,), **attrs)
class LuminanceSharpeningCompositor(GenericCompositor):
"""Create a high resolution composite by sharpening a low resolution using high resolution luminance.
This is done by converting to YCbCr colorspace, replacing Y, and convertin back to RGB.
"""
def __call__(self, projectables, *args, **kwargs):
"""Generate the composite."""
from trollimage.image import rgb2ycbcr, ycbcr2rgb
projectables = self.match_data_arrays(projectables)
luminance = projectables[0].copy()
luminance /= 100.
# Limit between min(luminance) ... 1.0
luminance = da.where(luminance > 1., 1., luminance)
# Get the enhanced version of the composite to be sharpened
rgb_img = enhance2dataset(projectables[1])
img = get_enhanced_image(dset)
data = np.rollaxis(np.dstack(img.channels), axis=2)
mask = dset.mask
if mask.ndim < data.ndim:
mask = np.expand_dims(mask, 0)
mask = np.repeat(mask, 3, 0)
elif mask.ndim > data.ndim:
mask = mask[0, :, :]
data = Dataset(np.ma.masked_array(data, mask=mask),
copy=False,
**dset.info)
return data
class RatioSharpenedRGB(GenericCompositor):
def __init__(self, *args, **kwargs):
self.high_resolution_band = kwargs.pop("high_resolution_band", "red")
if self.high_resolution_band not in ['red', 'green', 'blue', None]:
raise ValueError("RatioSharpenedRGB.high_resolution_band must "
"be one of ['red', 'green', 'blue', None]. Not "
"'{}'".format(self.high_resolution_band))
super(RatioSharpenedRGB, self).__init__(*args, **kwargs)
def __call__(self, datasets, optional_datasets=None, **info):
if len(datasets) != 3:
raise ValueError("Expected 3 datasets, got %d" % (len(datasets), ))
if not all(x.shape == datasets[0].shape for x in datasets[1:]) or \
(optional_datasets and
optional_datasets[0].shape != datasets[0].shape):
raise IncompatibleAreas('RatioSharpening requires datasets of '
| IR12.0 - IR10.8 | -4 to 2 K | gamma 1 |
+--------------------+--------------------+--------------------+
| IR10.8 - IR8.7 | 0 to 15 K | gamma 2.5 |
+--------------------+--------------------+--------------------+
| IR10.8 | 261 to 289 K | gamma 1 |
+--------------------+--------------------+--------------------+
"""
ch1 = sub_arrays(projectables[2], projectables[1])
ch2 = sub_arrays(projectables[1], projectables[0])
res = super(Dust, self).__call__((ch1, ch2,
projectables[1]),
*args, **kwargs)
return res
class RealisticColors(GenericCompositor):
def __call__(self, projectables, *args, **kwargs):
vis06 = projectables[0]
vis08 = projectables[1]
hrv = projectables[2]
try:
ch3 = 3 * hrv - vis06 - vis08
ch3.attrs = hrv.attrs
except ValueError:
raise IncompatibleAreas
ndvi = (vis08 - vis06) / (vis08 + vis06)
ndvi = np.where(ndvi < 0, 0, ndvi)
ch1 = ndvi * vis06 + (1 - ndvi) * vis08
def enhance2dataset(dset):
"""Return the enhancemened to dataset *dset* as an array."""
attrs = dset.attrs
img = get_enhanced_image(dset)
# Clip image data to interval [0.0, 1.0]
data = img.data.clip(0.0, 1.0)
data.attrs = attrs
# remove 'mode' if it is specified since it may have been updated
data.attrs.pop('mode', None)
# update mode since it may have changed (colorized/palettize)
data.attrs['mode'] = GenericCompositor.infer_mode(data)
return data
alpha['bands'] = 'A'
new_data.append(alpha)
new_data = xr.concat(new_data, dim='bands')
new_data.attrs['mode'] = data.attrs['mode'] + 'A'
data = new_data
return data
def zero_missing_data(data1, data2):
"""Replace NaN values with zeros in data1 if the data is valid in data2."""
nans = np.logical_and(np.isnan(data1), np.logical_not(np.isnan(data2)))
return data1.where(~nans, 0)
class RealisticColors(GenericCompositor):
"""Create a realistic colours composite for SEVIRI."""
def __call__(self, projectables, *args, **kwargs):
"""Generate the composite."""
projectables = self.match_data_arrays(projectables)
vis06 = projectables[0]
vis08 = projectables[1]
hrv = projectables[2]
try:
ch3 = 3 * hrv - vis06 - vis08
ch3.attrs = hrv.attrs
except ValueError:
raise IncompatibleAreas
ndvi = (vis08 - vis06) / (vis08 + vis06)
def __init__(self, name, common_channel_mask=True, **kwargs):
"""Collect custom configuration values.
Args:
common_channel_mask (bool): If True, mask all the channels with
a mask that combines all the invalid areas of the given data.
"""
self.common_channel_mask = common_channel_mask
super(GenericCompositor, self).__init__(name, **kwargs)
r = xr.DataArray(channels[:, :, 0].reshape(data.shape),
dims=data.dims, coords=data.coords,
attrs=data.attrs).where(mask)
g = xr.DataArray(channels[:, :, 1].reshape(data.shape),
dims=data.dims, coords=data.coords,
attrs=data.attrs).where(mask)
b = xr.DataArray(channels[:, :, 2].reshape(data.shape),
dims=data.dims, coords=data.coords,
attrs=data.attrs).where(mask)
res = super(PaletteCompositor, self).__call__((r, g, b), **data.attrs)
res.attrs['_FillValue'] = np.nan
return res
class DayNightCompositor(GenericCompositor):
"""A compositor that blends a day data with night data."""
def __init__(self, name, lim_low=85., lim_high=95., **kwargs):
"""Collect custom configuration values.
Args:
lim_low (float): lower limit of Sun zenith angle for the
blending of the given channels
lim_high (float): upper limit of Sun zenith angle for the
blending of the given channels
"""
self.lim_low = lim_low
self.lim_high = lim_high
super(DayNightCompositor, self).__init__(name, **kwargs)
raise IncompatibleAreas
ndvi = (vis08 - vis06) / (vis08 + vis06)
ndvi = np.where(ndvi < 0, 0, ndvi)
ch1 = ndvi * vis06 + (1 - ndvi) * vis08
ch1.attrs = vis06.attrs
ch2 = ndvi * vis08 + (1 - ndvi) * vis06
ch2.attrs = vis08.attrs
res = super(RealisticColors, self).__call__((ch1, ch2, ch3),
*args, **kwargs)
return res
class CloudCompositor(GenericCompositor):
def __init__(self, transition_min=258.15, transition_max=298.15,
transition_gamma=3.0, **kwargs):
"""Collect custom configuration values.
Args:
transition_min (float): Values below or equal to this are
clouds -> opaque white
transition_max (float): Values above this are
cloud free -> transparent
transition_gamma (float): Gamma correction to apply at the end
"""
self.transition_min = transition_min
self.transition_max = transition_max
self.transition_gamma = transition_gamma
class RGBCompositor(GenericCompositor):
def __call__(self, projectables, nonprojectables=None, **info):
import warnings
warnings.warn("RGBCompositor is deprecated, use GenericCompositor "
"instead.", DeprecationWarning)
if len(projectables) != 3:
raise ValueError("Expected 3 datasets, got %d" %
(len(projectables), ))
return super(RGBCompositor, self).__call__(projectables, **info)
class BWCompositor(GenericCompositor):
def __call__(self, projectables, nonprojectables=None, **info):
import warnings
warnings.warn("BWCompositor is deprecated, use GenericCompositor "
"instead.", DeprecationWarning)
return super(BWCompositor, self).__call__(projectables, **info)
class ColormapCompositor(GenericCompositor):
"""A compositor that uses colormaps."""
@staticmethod
def build_colormap(palette, dtype, info):
"""Create the colormap from the `raw_palette` and the valid_range."""