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
99 changes: 99 additions & 0 deletions satpy/composites/lightning.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/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 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"]

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 = data.max().values

Check warning on line 61 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L61

Added line #L61 was not covered by tests
ameraner marked this conversation as resolved.
Show resolved Hide resolved
# Compute the minimum time value based on the time range
begin_time = end_time - np.timedelta64(self.time_range, "m")

Check warning on line 63 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L63

Added line #L63 was not covered by tests
# Drop values that are bellow begin_time
data = data.where(data > begin_time, drop=True)

Check warning on line 65 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L65

Added line #L65 was not covered by tests
# Normalize the time values
normalized_data = (data - begin_time) / (end_time - begin_time)

Check warning on line 67 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L67

Added line #L67 was not covered by tests
# Ensure the result is still an xarray.DataArray
return xr.DataArray(normalized_data, dims=data.dims, coords=data.coords,attrs=attrs)

Check warning on line 69 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L69

Added line #L69 was not covered by tests


@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

Check warning on line 76 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L74-L76

Added lines #L74 - L76 were not covered by tests

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

Check warning on line 88 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L87-L88

Added lines #L87 - L88 were not covered by tests
# Attributes to describe the values range
return attrs

Check warning on line 90 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L90

Added line #L90 was not covered by tests


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)

Check warning on line 99 in satpy/composites/lightning.py

View check run for this annotation

Codecov / codecov/patch

satpy/composites/lightning.py#L95-L99

Added lines #L95 - L99 were not covered by tests
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 }