diff --git a/continuous_integration/environment.yaml b/continuous_integration/environment.yaml index 905cfa2f37..d131bad1e0 100644 --- a/continuous_integration/environment.yaml +++ b/continuous_integration/environment.yaml @@ -11,6 +11,7 @@ dependencies: - Cython - sphinx - cartopy + - panel>=0.12.7 - pillow - matplotlib - scipy diff --git a/satpy/composites/__init__.py b/satpy/composites/__init__.py index 90f4e67aac..f0b4b1922a 100644 --- a/satpy/composites/__init__.py +++ b/satpy/composites/__init__.py @@ -1101,7 +1101,8 @@ def __call__(self, projectables, *args, **kwargs): # Get the enhanced version of the RGB composite to be sharpened rgb_img = enhance2dataset(projectables[1]) - rgb_img *= luminance + # Ignore alpha band when applying luminance + rgb_img = rgb_img.where(rgb_img.bands == 'A', rgb_img * luminance) return super(SandwichCompositor, self).__call__(rgb_img, *args, **kwargs) diff --git a/satpy/etc/composites/ahi.yaml b/satpy/etc/composites/ahi.yaml index ef75c4c972..f29a36357f 100644 --- a/satpy/etc/composites/ahi.yaml +++ b/satpy/etc/composites/ahi.yaml @@ -2,19 +2,6 @@ sensor_name: visir/ahi modifiers: rayleigh_corrected: - modifier: !!python/name:satpy.modifiers.PSPRayleighReflectance - atmosphere: us-standard - aerosol_type: marine_clean_aerosol - prerequisites: - - wavelength: 0.64 - modifiers: [sunz_corrected] - optional_prerequisites: - - satellite_azimuth_angle - - satellite_zenith_angle - - solar_azimuth_angle - - solar_zenith_angle - - no_aerosol_rayleigh_corrected: modifier: !!python/name:satpy.modifiers.PSPRayleighReflectance atmosphere: us-standard aerosol_type: rayleigh_only @@ -48,9 +35,9 @@ composites: fractions: [0.6321, 0.2928, 0.0751] prerequisites: - name: B02 - modifiers: [sunz_corrected, no_aerosol_rayleigh_corrected] + modifiers: [sunz_corrected, rayleigh_corrected] - name: B03 - modifiers: [sunz_corrected, no_aerosol_rayleigh_corrected] + modifiers: [sunz_corrected, rayleigh_corrected] - name: B04 modifiers: [sunz_corrected] standard_name: none @@ -247,10 +234,10 @@ composites: compositor: !!python/name:satpy.composites.SelfSharpenedRGB prerequisites: - name: B03 - modifiers: [sunz_corrected, no_aerosol_rayleigh_corrected] + modifiers: [sunz_corrected, rayleigh_corrected] - name: green_true_color_reproduction - name: B01 - modifiers: [sunz_corrected, no_aerosol_rayleigh_corrected] + modifiers: [sunz_corrected, rayleigh_corrected] standard_name: true_color_reproduction # true_color_reducedsize_land: diff --git a/satpy/scene.py b/satpy/scene.py index 701aaf6a65..6b1f735f0c 100644 --- a/satpy/scene.py +++ b/satpy/scene.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2010-2017 Satpy developers +# Copyright (c) 2010-2022 Satpy developers # # This file is part of satpy. # @@ -71,14 +71,29 @@ def __init__(self, filenames=None, reader=None, filter_parameters=None, reader_kwargs=None): """Initialize Scene with Reader and Compositor objects. - To load data `filenames` and preferably `reader` must be specified. If `filenames` is provided without `reader` - then the available readers will be searched for a Reader that can support the provided files. This can take - a considerable amount of time so it is recommended that `reader` always be provided. Note without `filenames` - the Scene is created with no Readers available requiring Datasets to be added manually:: + To load data `filenames` and preferably `reader` must be specified:: + + scn = Scene(filenames=glob('/path/to/viirs/sdr/files/*'), reader='viirs_sdr') + + + If ``filenames`` is provided without ``reader`` then the available readers + will be searched for a Reader that can support the provided files. This + can take a considerable amount of time so it is recommended that + ``reader`` always be provided. Note without ``filenames`` the Scene is + created with no Readers available requiring Datasets to be added + manually:: scn = Scene() scn['my_dataset'] = Dataset(my_data_array, **my_info) + Further, notice that it is also possible to load a combination of files + or sets of files each requiring their specific reader. For that + ``filenames`` needs to be a `dict` (see parameters list below), e.g.:: + + scn = Scene(filenames={'nwcsaf-pps_nc': glob('/path/to/nwc/saf/pps/files/*'), + 'modis_l1b': glob('/path/to/modis/lvl1/files/*')}) + + Args: filenames (iterable or dict): A sequence of files that will be used to load data from. A ``dict`` object should map reader names to a list of filenames for that reader. diff --git a/satpy/tests/test_composites.py b/satpy/tests/test_composites.py index 77463872b2..20fbbfdd51 100644 --- a/satpy/tests/test_composites.py +++ b/satpy/tests/test_composites.py @@ -448,16 +448,25 @@ def test_compositor(self): np.testing.assert_allclose(res.data, 0.0, atol=1e-9) -class TestSandwichCompositor(unittest.TestCase): +class TestSandwichCompositor: """Test sandwich compositor.""" + # Test RGB and RGBA + @pytest.mark.parametrize( + "input_shape,bands", + [ + ((3, 2, 2), ['R', 'G', 'B']), + ((4, 2, 2), ['R', 'G', 'B', 'A']) + ] + ) @mock.patch('satpy.composites.enhance2dataset') - def test_compositor(self, e2d): + def test_compositor(self, e2d, input_shape, bands): """Test luminance sharpening compositor.""" from satpy.composites import SandwichCompositor - rgb_arr = da.from_array(np.random.random((3, 2, 2)), chunks=2) - rgb = xr.DataArray(rgb_arr, dims=['bands', 'y', 'x']) + rgb_arr = da.from_array(np.random.random(input_shape), chunks=2) + rgb = xr.DataArray(rgb_arr, dims=['bands', 'y', 'x'], + coords={'bands': bands}) lum_arr = da.from_array(100 * np.random.random((2, 2)), chunks=2) lum = xr.DataArray(lum_arr, dims=['y', 'x']) @@ -467,9 +476,15 @@ def test_compositor(self, e2d): res = comp([lum, rgb]) - for i in range(3): - np.testing.assert_allclose(res.data[i, :, :], - rgb_arr[i, :, :] * lum_arr / 100.) + for band in rgb: + if band.bands != 'A': + # Check compositor has modified this band + np.testing.assert_allclose(res.loc[band.bands].to_numpy(), + band.to_numpy() * lum_arr / 100.) + else: + # Check Alpha band remains intact + np.testing.assert_allclose(res.loc[band.bands].to_numpy(), + band.to_numpy()) # make sure the compositor doesn't modify the input data np.testing.assert_allclose(lum.values, lum_arr.compute())