pytroll / satpy

Python package for earth-observing satellite data processing
http://satpy.readthedocs.org/en/latest/
GNU General Public License v3.0
1.08k stars 298 forks source link

DayNightCompositor with `day_only` does not mask out night part if no alpha layer is present, defeating its purpose #3003

Open gerritholl opened 2 days ago

gerritholl commented 2 days ago

Describe the bug

When using the DayNightCompositor with the parameter day_night: day_only and include_alpha: False, the night part is not set to fill value and the resulting geotiff (mode L or mode RGB) is the same as without using the DayNightCompositor at all.

To Reproduce

import tempfile
import pathlib
import os
import rasterio

config = """sensor/name: visir

composites:
   day_vis_06:
    compositor: !!python/name:satpy.composites.DayNightCompositor
    prerequisites:
      - vis_06
    day_night: day_only
    include_alpha: False
    standard_name: image_ready
"""
with tempfile.TemporaryDirectory() as td:
    p = pathlib.Path(td)
    fn = p / "composites" / "fci.yaml"
    fn.parent.mkdir(exist_ok=True, parents=True)
    with fn.open(mode="wt", encoding="ascii") as fp:
        fp.write(config)
    os.environ["SATPY_CONFIG_PATH"] = td

    import hdf5plugin
    from satpy import Scene
    from glob import glob
    from satpy.utils import debug_on; debug_on()

    fci_files = glob(f"/media/nas/x23352/MTG/FCI/L1c-cases/20241025-nighttime-convection-mediterranean/09/*FDHSI*C_0055_*.nc")
    sc = Scene(filenames={"fci_l1c_nc": fci_files})
    sc.load(["day_vis_06"])
    ls = sc.resample("eurol")
    out = f"{td:s} / out.tif"
    ls.save_dataset("day_vis_06",
                    out,
                    write="geotiff",
                    fill_value=0)

    src = rasterio.open(out)
    arr = src.read(1)
    print(arr[0:5, 0:5])

Expected behavior

I expect that those pixels, which are night-time, are set to zero, in accordance to the fill value, so that supporting image viewers such as QGIS will display those pixels as transparent, like they do with space pixels.

Actual results

[[1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]]

Environment Info:

Additional context

It seems that the DayNightCompositor does not set the night time pixels to fill value at all, but leaves them at zero:

In [18]: print(sc["day_vis_06"][3000:4000:100, 3000:4000:100].compute())
<xarray.DataArray 'add-b998c5399f861c240d74f380f4bda087' (y: 10, x: 10)> Size: 400B
array([[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan],
       [nan, nan, nan, nan, nan, nan, nan, nan, nan,  0.],
       [nan, nan, nan, nan, nan, nan, nan, nan,  0.,  0.],
       [nan, nan, nan, nan, nan, nan, nan,  0.,  0.,  0.],
       [nan, nan, nan, nan, nan, nan,  0.,  0.,  0.,  0.],
       [nan, nan, nan, nan, nan,  0.,  0.,  0.,  0.,  0.],
       [nan, nan, nan, nan,  0.,  0.,  0.,  0.,  0.,  0.],
       [nan, nan, nan,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [nan, nan,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [nan,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]], dtype=float32)

Then get_enhanced_image does not know those pixels should be masked, and sets them to one because it cannot know those pixels should be considered masked rather than physical zero values.

gerritholl commented 2 days ago

The documentation contradicts the implementation and the test. The documentation claims that the night is replaced with nans:

https://github.com/pytroll/satpy/blob/096d5d9cc51aa711d740af95fea628b7cee18f7b/satpy/composites/__init__.py#L713-L716

The test asserts that the night is replaced with zeroes:

https://github.com/pytroll/satpy/blob/096d5d9cc51aa711d740af95fea628b7cee18f7b/satpy/tests/test_composites.py#L527-L531

gerritholl commented 2 days ago

This was added by @yukaribbba in https://github.com/pytroll/satpy/pull/2358 to solve https://github.com/pytroll/satpy/issues/2357. Apparently, a black background was desired at the time, but the documentation still contradicts the implementation.