Source code for satpy.composites.glm

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2019 Satpy developers
#
# This file is part of satpy.
#
# satpy is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# satpy is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# satpy.  If not, see <http://www.gnu.org/licenses/>.
"""Composite classes for the GLM instrument."""

import logging

import xarray as xr

from satpy.composites import GenericCompositor
from satpy.writers import get_enhanced_image

LOG = logging.getLogger(__name__)


[docs] class HighlightCompositor(GenericCompositor): """Highlight pixels of a layer by an amount determined by a secondary layer. The highlighting is applied per channel to either add or subtract an intensity from the primary image. In the addition case, the code is essentially doing:: highlight_factor = (highlight_data - min_highlight) / (max_highlight - min_highlight) channel_result = primary_data + highlight_factor * max_factor The ``max_factor`` is defined per channel and can be positive for an additive effect, negative for a subtractive effect, or zero for no effect. """ def __init__(self, name, min_highlight=0.0, max_highlight=10.0, # noqa: D417 max_factor=(0.8, 0.8, -0.8, 0), **kwargs): """Initialize composite with highlight factor options. Args: min_highlight (float): Minimum raw value of the "highlight" data that will be used for linearly scaling the data along with ``max_highlight``. max_highlight (float): Maximum raw value of the "highlight" data that will be used for linearly scaling the data along with ``min_highlight``. max_factor (tuple): Maximum effect that the highlight data can have on each channel of the primary image data. This will be multiplied by the linearly scaled highlight data and then added or subtracted from the highlight channels. See class docstring for more information. By default this is set to ``(0.8, 0.8, -0.8, 0)`` meaning the Red and Green channel will be added to by at most 0.8, the Blue channel will be subtracted from by at most 0.8 (resulting in yellow highlights), and the Alpha channel will not be affected. """ self.min_highlight = min_highlight self.max_highlight = max_highlight self.max_factor = max_factor super().__init__(name, **kwargs)
[docs] @staticmethod def _get_enhanced_background_data(background_layer): img = get_enhanced_image(background_layer) img.data = img.data.clip(0.0, 1.0) img = img.convert("RGBA") return img.data
[docs] def _get_highlight_factor(self, highlight_data): factor = (highlight_data - self.min_highlight) / (self.max_highlight - self.min_highlight) factor = factor.where(factor.notnull(), 0) return factor
[docs] def _apply_highlight_effect(self, background_data, factor): new_channels = [] for max_factor, band_name in zip(self.max_factor, "RGBA"): new_channel = background_data.sel(bands=[band_name]) if max_factor != 0 or max_factor is not None: new_channel = new_channel + factor * max_factor new_channels.append(new_channel) return new_channels
[docs] def _update_attrs(self, new_data, background_layer, highlight_layer): new_data.attrs = background_layer.attrs.copy() new_data.attrs["units"] = 1 new_sensors = self._get_sensors((highlight_layer, background_layer)) new_data.attrs.update({ "sensor": new_sensors, })
def __call__(self, projectables, optional_datasets=None, **attrs): """Create RGBA image with highlighted pixels.""" highlight_product, background_layer = self.match_data_arrays(projectables) background_data = self._get_enhanced_background_data(background_layer) # Adjust the colors of background by highlight layer factor = self._get_highlight_factor(highlight_product) new_channels = self._apply_highlight_effect(background_data, factor) new_data = xr.concat(new_channels, dim="bands") self._update_attrs(new_data, background_layer, highlight_product) return super(HighlightCompositor, self).__call__((new_data,), **attrs)