Loading an image with generic_image, then writing with geotiff, changes the image
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.2k
- Forks
- 335
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 10
Description
Describe the bug
When I load an image with the generic_image reader and immediately write it out again, the image changes. This happens because the generic_image reader returns float data, and then a default enhancement gets applied. However, not enhancing the data at all is even worse.
To Reproduce
from satpy import Scene
from glob import glob
seviri_files = glob("/media/nas/x21308/scratch/SEVIRI/202103300900/H-000*")
sc = Scene(filenames={"seviri_l1b_hrit": seviri_files})
sc.load(["natural_color"])
sc.save_datasets(writer="geotiff", filename="/tmp/natural-color-1.tif")
sc2 = Scene(filenames={"generic_image": ["/tmp/natural-color-1.tif"]})
sc2.load(["image"])
sc2.save_datasets(writer="geotiff", filename="/tmp/natural-color-2.tif")
Expected behavior
I expect both images to look the same.
Actual results
There is a difference, because the second image is getting re-enhanced:
[DEBUG: 2025-09-18 11:22:19 : satpy.readers.core.yaml_reader] Reading ('/home/gholl/checkouts/satpy/satpy/etc/readers/seviri_l1b_hrit.yaml',)
[DEBUG: 2025-09-18 11:22:19 : satpy.readers.core.yaml_reader] Assigning to seviri_l1b_hrit: ['/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000017___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000018___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000010___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000011___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000016___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000019___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000009___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000020___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000014___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000012___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000013___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000022___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000023___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000015___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000024___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000021___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-HRV______-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_016___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_039___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_087___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_097___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_108___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_120___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-IR_134___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS006___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-VIS008___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_062___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000005___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000003___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000006___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000002___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000001___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000004___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000007___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-WV_073___-000008___-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-_________-PRO______-202103300900-__', '/media/nas/x21308/scratch/SEVIRI/202103300900/H-000-MSG4__-MSG4________-_________-EPI______-202103300900-__']
[INFO: 2025-09-18 11:22:19 : hrit_msg] No IMPF configuration field found in prologue.
[DEBUG: 2025-09-18 11:22:19 : satpy.composites.config_loader] Looking for composites config file seviri.yaml
[DEBUG: 2025-09-18 11:22:19 : pyorbital.tlefile] Path to the Pyorbital configuration (where e.g. platforms.txt is found): /home/gholl/miniforge3/envs/py313/lib/python3.13/site-packages/pyorbital/etc
[DEBUG: 2025-09-18 11:22:19 : satpy.composites.config_loader] Looking for composites config file visir.yaml
[DEBUG: 2025-09-18 11:22:19 : satpy.readers.core.yaml_reader] Requested orientation for Dataset None is 'native' (default). No flipping is applied.
[DEBUG: 2025-09-18 11:22:19 : satpy.readers.core.yaml_reader] Requested orientation for Dataset None is 'native' (default). No flipping is applied.
[DEBUG: 2025-09-18 11:22:19 : satpy.readers.core.yaml_reader] Requested orientation for Dataset None is 'native' (default). No flipping is applied.
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Applying sun zen correction
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Computing sun zenith angles.
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Apply the standard sun-zenith correction [1/cos(sunz)]
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Applying sun zen correction
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Computing sun zenith angles.
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Apply the standard sun-zenith correction [1/cos(sunz)]
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Applying sun zen correction
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Computing sun zenith angles.
[DEBUG: 2025-09-18 11:22:19 : satpy.modifiers.geometry] Apply the standard sun-zenith correction [1/cos(sunz)]
[DEBUG: 2025-09-18 11:22:19 : satpy.scene] Unloading dataset: DataID(name='IR_016', wavelength=WavelengthRange(min=1.5, central=1.64, max=1.78, unit='µm'), resolution=3000.403165817, calibration=<1>, modifiers=())
[DEBUG: 2025-09-18 11:22:19 : satpy.scene] Unloading dataset: DataID(name='VIS008', wavelength=WavelengthRange(min=0.74, central=0.81, max=0.88, unit='µm'), resolution=3000.403165817, calibration=<1>, modifiers=())
[DEBUG: 2025-09-18 11:22:19 : satpy.scene] Unloading dataset: DataID(name='VIS006', wavelength=WavelengthRange(min=0.56, central=0.635, max=0.71, unit='µm'), resolution=3000.403165817, calibration=<1>, modifiers=())
[DEBUG: 2025-09-18 11:22:19 : satpy.scene] Unloading dataset: DataID(name='IR_016', wavelength=WavelengthRange(min=1.5, central=1.64, max=1.78, unit='µm'), resolution=3000.403165817, calibration=<1>, modifiers=('sunz_corrected',))
[DEBUG: 2025-09-18 11:22:19 : satpy.scene] Unloading dataset: DataID(name='VIS008', wavelength=WavelengthRange(min=0.74, central=0.81, max=0.88, unit='µm'), resolution=3000.403165817, calibration=<1>, modifiers=('sunz_corrected',))
[DEBUG: 2025-09-18 11:22:19 : satpy.scene] Unloading dataset: DataID(name='VIS006', wavelength=WavelengthRange(min=0.56, central=0.635, max=0.71, unit='µm'), resolution=3000.403165817, calibration=<1>, modifiers=('sunz_corrected',))
[DEBUG: 2025-09-18 11:22:19 : satpy.writers.core.config] Reading ['/home/gholl/checkouts/satpy/satpy/etc/writers/geotiff.yaml']
[DEBUG: 2025-09-18 11:22:19 : rasterio.session] Could not import boto3, continuing with reduced functionality.
[DEBUG: 2025-09-18 11:22:20 : satpy.enhancements.enhancer] Adding enhancement configuration from file: /home/gholl/checkouts/satpy/satpy/etc/enhancements/generic.yaml
[DEBUG: 2025-09-18 11:22:20 : satpy.enhancements.enhancer] Adding enhancement configuration from file: /home/gholl/checkouts/pytroll-dwd-config/dev/enhancements/generic.yaml
[DEBUG: 2025-09-18 11:22:20 : satpy.enhancements.enhancer] Adding enhancement configuration from file: /home/gholl/checkouts/pytroll-dwd-config/oper/enhancements/generic.yaml
[DEBUG: 2025-09-18 11:22:20 : satpy.enhancements.enhancer] Adding enhancement configuration from file: /home/gholl/checkouts/satpy/satpy/etc/enhancements/seviri.yaml
[DEBUG: 2025-09-18 11:22:20 : satpy.enhancements.enhancer] Data for DataID(name='natural_color', resolution=3000.403165817) will be enhanced with options:
[{'name': 'stretch', 'method': <function stretch at 0x7fde9f5716c0>, 'kwargs': {'stretch': 'crude', 'min_stretch': 0, 'max_stretch': 120}}, {'name': 'gamma', 'method': <function gamma at 0x7fde9f571760>, 'kwargs': {'gamma': 1.8}}]
[DEBUG: 2025-09-18 11:22:20 : trollimage.xrimage] Applying stretch crude with parameters {'min_stretch': 0, 'max_stretch': 120}
[DEBUG: 2025-09-18 11:22:20 : trollimage.xrimage] Applying gamma 1.8
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] Entering env context: <rasterio.env.Env object at 0x7fde9f1541a0>
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] Starting outermost env
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] No GDAL environment exists
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] New GDAL environment <rasterio._env.GDALEnv object at 0x7fdea26925f0> created
[DEBUG: 2025-09-18 11:22:20 : rasterio._filepath] Installing FilePath filesystem handler plugin...
[DEBUG: 2025-09-18 11:22:20 : rasterio._env] GDAL_DATA found in environment.
[DEBUG: 2025-09-18 11:22:20 : rasterio._env] PROJ_DATA found in environment.
[DEBUG: 2025-09-18 11:22:20 : rasterio._env] Started GDALEnv: self=<rasterio._env.GDALEnv object at 0x7fdea26925f0>.
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] Entered env context: <rasterio.env.Env object at 0x7fde9f1541a0>
[DEBUG: 2025-09-18 11:22:20 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:20 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:20 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:20 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] Exiting env context: <rasterio.env.Env object at 0x7fde9f1541a0>
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] Cleared existing <rasterio._env.GDALEnv object at 0x7fdea26925f0> options
[DEBUG: 2025-09-18 11:22:20 : rasterio._env] Stopped GDALEnv <rasterio._env.GDALEnv object at 0x7fdea26925f0>.
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] Exiting outermost env
[DEBUG: 2025-09-18 11:22:20 : rasterio.env] Exited env context: <rasterio.env.Env object at 0x7fde9f1541a0>
[INFO: 2025-09-18 11:22:20 : satpy.writers.core.base] Computing and writing results...
[DEBUG: 2025-09-18 11:22:22 : satpy.readers.core.yaml_reader] Reading ('/home/gholl/checkouts/satpy/satpy/etc/readers/generic_image.yaml',)
[DEBUG: 2025-09-18 11:22:22 : satpy.readers.core.yaml_reader] Assigning to generic_image: ['/tmp/natural-color-1.tif']
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Entering env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Starting outermost env
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] No GDAL environment exists
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] New GDAL environment <rasterio._env.GDALEnv object at 0x7fde9f2800d0> created
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] GDAL_DATA found in environment.
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] PROJ_DATA found in environment.
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] Started GDALEnv: self=<rasterio._env.GDALEnv object at 0x7fde9f2800d0>.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Entered env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Sharing flag: 0
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Dataset <open DatasetReader name='/tmp/natural-color-1.tif' mode='r'> is started.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exiting env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Cleared existing <rasterio._env.GDALEnv object at 0x7fde9f2800d0> options
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] Stopped GDALEnv <rasterio._env.GDALEnv object at 0x7fde9f2800d0>.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exiting outermost env
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exited env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Entering env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Starting outermost env
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] No GDAL environment exists
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] New GDAL environment <rasterio._env.GDALEnv object at 0x7fdea263b700> created
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] GDAL_DATA found in environment.
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] PROJ_DATA found in environment.
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] Started GDALEnv: self=<rasterio._env.GDALEnv object at 0x7fdea263b700>.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Entered env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Sharing flag: 0
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Dataset <open DatasetReader name='/tmp/natural-color-1.tif' mode='r'> is started.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exiting env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Cleared existing <rasterio._env.GDALEnv object at 0x7fdea263b700> options
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] Stopped GDALEnv <rasterio._env.GDALEnv object at 0x7fdea263b700>.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exiting outermost env
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exited env context: <rasterio.env.Env object at 0x7fde9f248a50>
[DEBUG: 2025-09-18 11:22:22 : satpy.composites.config_loader] Looking for composites config file images.yaml
[DEBUG: 2025-09-18 11:22:22 : satpy.composites.config_loader] No composite config found called images.yaml
[DEBUG: 2025-09-18 11:22:22 : satpy.readers.generic_image] Reading 'image.'
[DEBUG: 2025-09-18 11:22:22 : satpy.writers.core.config] Reading ['/home/gholl/checkouts/satpy/satpy/etc/writers/geotiff.yaml']
[DEBUG: 2025-09-18 11:22:22 : satpy.enhancements.enhancer] Adding enhancement configuration from file: /home/gholl/checkouts/satpy/satpy/etc/enhancements/generic.yaml
[DEBUG: 2025-09-18 11:22:22 : satpy.enhancements.enhancer] Adding enhancement configuration from file: /home/gholl/checkouts/pytroll-dwd-config/dev/enhancements/generic.yaml
[DEBUG: 2025-09-18 11:22:22 : satpy.enhancements.enhancer] Adding enhancement configuration from file: /home/gholl/checkouts/pytroll-dwd-config/oper/enhancements/generic.yaml
[DEBUG: 2025-09-18 11:22:22 : satpy.enhancements.enhancer] Data for DataID(name='image', modifiers=()) will be enhanced with options:
[{'name': 'stretch', 'method': <function stretch at 0x7fde9f5716c0>, 'kwargs': {'stretch': 'linear'}}]
[DEBUG: 2025-09-18 11:22:22 : trollimage.xrimage] Applying stretch linear with parameters {}
[DEBUG: 2025-09-18 11:22:22 : trollimage.xrimage] Perform a linear contrast stretch.
[DEBUG: 2025-09-18 11:22:22 : trollimage.xrimage] Calculate the histogram quantiles:
[DEBUG: 2025-09-18 11:22:22 : trollimage.xrimage] Left and right quantiles: 0.005 0.005
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Entering env context: <rasterio.env.Env object at 0x7fde9f4f36f0>
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Starting outermost env
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] No GDAL environment exists
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] New GDAL environment <rasterio._env.GDALEnv object at 0x7fde9f57e1a0> created
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] GDAL_DATA found in environment.
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] PROJ_DATA found in environment.
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] Started GDALEnv: self=<rasterio._env.GDALEnv object at 0x7fde9f57e1a0>.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Entered env context: <rasterio.env.Env object at 0x7fde9f4f36f0>
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio._base] Nodata success: 0, Nodata value: 0.000000
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exiting env context: <rasterio.env.Env object at 0x7fde9f4f36f0>
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Cleared existing <rasterio._env.GDALEnv object at 0x7fde9f57e1a0> options
[DEBUG: 2025-09-18 11:22:22 : rasterio._env] Stopped GDALEnv <rasterio._env.GDALEnv object at 0x7fde9f57e1a0>.
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exiting outermost env
[DEBUG: 2025-09-18 11:22:22 : rasterio.env] Exited env context: <rasterio.env.Env object at 0x7fde9f4f36f0>
[INFO: 2025-09-18 11:22:22 : satpy.writers.core.base] Computing and writing results...
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata value read from file: None
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata values: [None]
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] all_valid: False
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] mask_flags: ([<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.all_valid: 1>])
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Jump straight to _read()
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Window: Window(col_off=0, row_off=0, width=3712, height=3712)
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] IO window xoff=0.0 yoff=0.0 width=3712.0 height=3712.0
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata value read from file: None
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata values: [None]
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] all_valid: False
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] mask_flags: ([<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.all_valid: 1>])
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Jump straight to _read()
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Window: Window(col_off=0, row_off=0, width=3712, height=3712)
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] IO window xoff=0.0 yoff=0.0 width=3712.0 height=3712.0
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata value read from file: None
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata values: [None]
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] all_valid: False
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] mask_flags: ([<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.all_valid: 1>])
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Jump straight to _read()
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Window: Window(col_off=0, row_off=0, width=3712, height=3712)
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] IO window xoff=0.0 yoff=0.0 width=3712.0 height=3712.0
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata value read from file: None
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Output nodata values: [None]
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] all_valid: False
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] mask_flags: ([<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.per_dataset: 2>, <MaskFlags.alpha: 4>], [<MaskFlags.all_valid: 1>])
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Jump straight to _read()
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] Window: Window(col_off=0, row_off=0, width=3712, height=3712)
[DEBUG: 2025-09-18 11:22:22 : rasterio._io] IO window xoff=0.0 yoff=0.0 width=3712.0 height=3712.0
Screenshots
Environment Info:
- OS: openSUSE Leap 15.6
- Satpy Version: main
Additional context
I tried to create a custom reader with a standard name, then set this to image_ready, but this just makes the situation worse:
reader:
name: special-image
description: reads RGBs from geotiff files
reader: !!python/name:satpy.readers.core.yaml_reader.FileYAMLReader
sensors: [world-images]
file_types:
special-image:
file_reader: !!python/name:satpy.readers.generic_image.GenericImageFileHandler
file_patterns:
- "{name}.tif"
datasets:
special-image:
file_type: special-image
name: special-image
standard_name: image_ready
What happens here is that trollimage is getting data with floats between 0 and 255, but expects floats between 0 and 1.
As a workaround, this enhancement works (with standard_name: rgb_image):
rgb_image:
standard_name: rgb_image
operations:
- name: stretch
method: !!python/name:satpy.enhancements.contrast.stretch
kwargs:
stretch: crude
min_stretch: [0, 0, 0]
max_stretch: [255, 255, 255]
As a solution, if the GenericImageFileHandler would return integer data, I think satpy wouldn't enhance the data and the round trip load/save should work.
Why am I doing this? I'm creating an RGB world composite by writing each component image to a joint world area, then loading those with a dedicated reader and combining them with the LongitudeMaskingCompositor.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the round trip in the issue using Satpy's generic_image reader and geotiff writer. Inspect how float data from generic_image is enhanced before writing, then verify the chosen behavior against the original and rewritten images. Done means loading and rewriting the GeoTIFF does not visibly change the image.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100