Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flash age compositor for li instruments #2895

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
106 changes: 106 additions & 0 deletions satpy/composites/lightning.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/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 LI instrument."""

import logging
import sys

import numpy as np
import xarray as xr

from satpy.composites import CompositeBase

LOG = logging.getLogger(__name__)


class LightningTimeCompositor(CompositeBase):
"""Class used to create the flash_age compositor usefull for lighting event visualisation.

The datas used are dates related to the lightning event that should be normalised between
0 and 1. The value 1 corresponds to the latest lightning event and the value 0 corresponds
to the latest lightning event - time_range. The time_range is defined in the satpy/etc/composites/li.yaml
and is in minutes.
"""
def __init__(self, name, prerequisites=None, optional_prerequisites=None, **kwargs):
"""Initialisation of the class."""
self.name = name
super().__init__(name, prerequisites, optional_prerequisites, **kwargs)
# Get the time_range which is in minute
self.time_range = self.attrs["time_range"]
self.standard_name = self.attrs["standard_name"]
self.reference_time = self.attrs["reference_time"]


def _normalize_time(self,data:xr.DataArray,attrs:dict)->xr.DataArray:
"""Normalised the time in the range between [end_time,end_time - time_range].

The range of the normalised data is between 0 and 1 where 0 corresponds to the date end_time - time_range
and 1 to the end_time. Where end_times represent the latest lightning event and time_range is the range of
time you want to see the event.The dates that are earlier to end_time - time_range are removed.

Args:
data (xr.DataArray): datas containing dates to be normalised
attrs (dict): Attributes suited to the flash_age composite

Returns:
xr.DataArray: Normalised time
"""
# Compute the maximum time value
end_time = np.array(np.datetime64(data.attrs[self.reference_time]))
# Compute the minimum time value based on the time range
begin_time = end_time - np.timedelta64(self.time_range, "m")
# Drop values that are bellow begin_time
data = data.where(data >= begin_time, drop=True)
# exit if data is empty afer filtering
if data.size == 0 :
LOG.error(f"All the flash_age events happened before {begin_time}")
sys.exit(1)
# Normalize the time values
normalized_data = (data - begin_time) / (end_time - begin_time)
# Ensure the result is still an xarray.DataArray
return xr.DataArray(normalized_data, dims=data.dims, coords=data.coords,attrs=attrs)


@staticmethod
def _update_missing_metadata(existing_attrs, new_attrs):
for key, val in new_attrs.items():
if key not in existing_attrs and val is not None:
existing_attrs[key] = val

def _redefine_metadata(self,attrs:dict)->dict:
"""Modify the standard_name and name metadatas.

Args:
attrs (dict): data's attributes

Returns:
dict: atualised attributes
"""
attrs["name"] = self.standard_name
attrs["standard_name"] =self.standard_name
# Attributes to describe the values range
return attrs


def __call__(self,projectables, nonprojectables=None, **attrs):
"""Normalise the dates."""
data = projectables[0]
new_attrs = data.attrs.copy()
self._update_missing_metadata(new_attrs, attrs)
new_attrs = self._redefine_metadata(new_attrs)
return self._normalize_time(data,new_attrs)
31 changes: 20 additions & 11 deletions satpy/etc/composites/li.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,69 +10,78 @@ composites:
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: acc_flash
prerequisites:
- flash_accumulation
- flash_accumulation
acc_flash_alpha:
description: Composite to colorise the AF product using the flash accumulation with transparency
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: acc_flash_alpha
prerequisites:
- flash_accumulation
- flash_accumulation

acc_flash_area:
description: Composite to colorise the AFA product using the flash area
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: acc_flash_area
prerequisites:
- accumulated_flash_area
- accumulated_flash_area
acc_flash_area_alpha:
description: Composite to colorise the AFA product using the flash area with transparency
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: acc_flash_area_alpha
prerequisites:
- accumulated_flash_area
- accumulated_flash_area

acc_flash_radiance:
description: Composite to colorise the AFR product using the flash radiance
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: lightning_radiance
prerequisites:
- flash_radiance
- flash_radiance
acc_flash_radiance_alpha:
description: Composite to colorise the AFR product using the flash radiance with transparency
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: lightning_radiance_alpha
prerequisites:
- flash_radiance
- flash_radiance

flash_radiance:
description: Composite to colorise the LFL product using the flash radiance
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: lightning_radiance
prerequisites:
- radiance
- radiance
flash_radiance_alpha:
description: Composite to colorise the LFL product using the flash radiance with transparency
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: lightning_radiance_alpha
prerequisites:
- radiance
- radiance

group_radiance:
description: Composite to colorise the LGR product using the flash radiance
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: lightning_radiance
prerequisites:
- radiance
- radiance
group_radiance_alpha:
description: Composite to colorise the LGR product using the flash radiance with transparency
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: lightning_radiance_alpha
prerequisites:
- radiance
- radiance

# DEPRECATED, USE acc_flash_area INSTEAD
flash_area:
compositor: !!python/name:satpy.composites.SingleBandCompositor
standard_name: acc_flash_area
prerequisites:
- accumulated_flash_area
- accumulated_flash_area

flash_age:
description: Composite to colorise the LFL product using the flash time
compositor: !!python/name:satpy.composites.lightning.LightningTimeCompositor
standard_name: lightning_time
time_range: 60 # range for colormap in minutes
reference_time: end_time
prerequisites:
- flash_time
94 changes: 59 additions & 35 deletions satpy/etc/enhancements/li.yaml
Original file line number Diff line number Diff line change
@@ -1,60 +1,84 @@
enhancements:
# note that the colormap parameters are tuned for 5 minutes of files accumulation
# these are tentative recipes that will need to be further tuned as we gain experience with LI data
# note that the colormap parameters are tuned for 5 minutes of files accumulation
# these are tentative recipes that will need to be further tuned as we gain experience with LI data

acc_flash:
standard_name: acc_flash
operations:
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {colors: ylorrd, min_value: 0, max_value: 5}
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- { colors: ylorrd, min_value: 0, max_value: 5 }

acc_flash_alpha:
standard_name: acc_flash_alpha
operations:
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {colors: ylorrd, min_value: 0, max_value: 5,
min_alpha: 120, max_alpha: 180}
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {
colors: ylorrd,
min_value: 0,
max_value: 5,
min_alpha: 120,
max_alpha: 180,
}

acc_flash_area:
standard_name: acc_flash_area
operations:
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {colors: ylorrd, min_value: 0, max_value: 20}
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- { colors: ylorrd, min_value: 0, max_value: 20 }

acc_flash_area_alpha:
standard_name: acc_flash_area_alpha
operations:
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {colors: ylorrd, min_value: 0, max_value: 20,
min_alpha: 120, max_alpha: 180}
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {
colors: ylorrd,
min_value: 0,
max_value: 20,
min_alpha: 120,
max_alpha: 180,
}

lightning_radiance:
standard_name: lightning_radiance
operations:
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {colors: ylorrd, min_value: 0, max_value: 1000}
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- { colors: ylorrd, min_value: 0, max_value: 1000 }

lightning_radiance_alpha:
standard_name: lightning_radiance_alpha
operations:
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {colors: ylorrd, min_value: 0, max_value: 1000,
min_alpha: 120, max_alpha: 180}
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- {
colors: ylorrd,
min_value: 0,
max_value: 1000,
min_alpha: 120,
max_alpha: 180,
}

lightning_time:
standard_name: lightning_time
operations:
- name: colorize
method: !!python/name:satpy.enhancements.colorize
kwargs:
palettes:
- { colors: ylorrd, min_value: 0, max_value: 1 }
Loading
Loading