diff --git a/doc/source/composites.rst b/doc/source/composites.rst
index 4d457c40d9..4804aba0df 100644
--- a/doc/source/composites.rst
+++ b/doc/source/composites.rst
@@ -516,7 +516,6 @@ Enhancing the images
- stretch
- gamma
- invert
- - crefl_scaling
- cira_stretch
- lookup
- colorize
diff --git a/doc/source/enhancements.rst b/doc/source/enhancements.rst
index 0386f6a4c7..9623c1b120 100644
--- a/doc/source/enhancements.rst
+++ b/doc/source/enhancements.rst
@@ -60,11 +60,6 @@ gamma
invert
------
-crefl_scaling
--------------
-
-Deprecated. Use 'piecewise_linear_stretch' instead.
-
piecewise_linear_stretch
------------------------
diff --git a/satpy/_config.py b/satpy/_config.py
index 58bcc70452..2b583c435c 100644
--- a/satpy/_config.py
+++ b/satpy/_config.py
@@ -25,8 +25,9 @@
import sys
import tempfile
from collections import OrderedDict
-from importlib.metadata import entry_points
+from importlib.metadata import EntryPoint, entry_points
from pathlib import Path
+from typing import Iterable
try:
from importlib.resources import files as impr_files # type: ignore
@@ -123,10 +124,10 @@ def get_config_path_safe():
return config_path
-def get_entry_points_config_dirs(name, include_config_path=True):
+def get_entry_points_config_dirs(group_name: str, include_config_path: bool = True) -> list[str]:
"""Get the config directories for all entry points of given name."""
- dirs = []
- for entry_point in cached_entry_points().get(name, []):
+ dirs: list[str] = []
+ for entry_point in cached_entry_point(group_name):
module = _entry_point_module(entry_point)
new_dir = str(impr_files(module) / "etc")
if not dirs or dirs[-1] != new_dir:
@@ -137,12 +138,21 @@ def get_entry_points_config_dirs(name, include_config_path=True):
@cache
-def cached_entry_points():
- """Return entry_points.
+def cached_entry_point(group_name: str) -> Iterable[EntryPoint]:
+ """Return entry_point for specified ``group``.
+
+ This is a dummy proxy to allow caching and provide compatibility between
+ versions of Python and importlib_metadata.
- This is a dummy proxy to allow caching.
"""
- return entry_points()
+ try:
+ # mypy in pre-commit currently checks for Python 3.8 compatibility
+ # this line is for Python 3.10+ so it will fail checks
+ return entry_points(group=group_name) # type: ignore
+ except TypeError:
+ # Python <3.10
+ entry_points_list = entry_points()
+ return entry_points_list.get(group_name, [])
def _entry_point_module(entry_point):
diff --git a/satpy/enhancements/__init__.py b/satpy/enhancements/__init__.py
index 29f2cbdf54..b0fa2b8aa3 100644
--- a/satpy/enhancements/__init__.py
+++ b/satpy/enhancements/__init__.py
@@ -17,7 +17,6 @@
import logging
import os
-import warnings
from collections import namedtuple
from functools import wraps
from numbers import Number
@@ -126,18 +125,6 @@ def wrapper(data, **kwargs):
return on_dask_array(wrapper)
-def crefl_scaling(img, **kwargs):
- """Apply non-linear stretch used by CREFL-based RGBs."""
- LOG.debug("Applying the crefl_scaling")
- warnings.warn(
- "'crefl_scaling' is deprecated, use 'piecewise_linear_stretch' instead.",
- DeprecationWarning,
- stacklevel=2
- )
- img.data.data = img.data.data / 100
- return piecewise_linear_stretch(img, xp=kwargs['idx'], fp=kwargs['sc'], reference_scale_factor=255)
-
-
def piecewise_linear_stretch(
img: XRImage,
xp: ArrayLike,
diff --git a/satpy/readers/ami_l1b.py b/satpy/readers/ami_l1b.py
index 9070da9252..4569b996fa 100644
--- a/satpy/readers/ami_l1b.py
+++ b/satpy/readers/ami_l1b.py
@@ -161,10 +161,10 @@ def get_orbital_parameters(self):
sc_position = self.nc['sc_position'].attrs['sc_position_center_pixel']
# convert ECEF coordinates to lon, lat, alt
- ecef = pyproj.Proj(proj='geocent', a=a, b=b)
- lla = pyproj.Proj(proj='latlong', a=a, b=b)
- sc_position = pyproj.transform(
- ecef, lla, sc_position[0], sc_position[1], sc_position[2])
+ ecef = pyproj.CRS.from_dict({"proj": "geocent", "a": a, "b": b})
+ lla = pyproj.CRS.from_dict({"proj": "latlong", "a": a, "b": b})
+ transformer = pyproj.Transformer.from_crs(ecef, lla)
+ sc_position = transformer.transform(sc_position[0], sc_position[1], sc_position[2])
orbital_parameters = {
'projection_longitude': float(lon_0),
diff --git a/satpy/readers/utils.py b/satpy/readers/utils.py
index aae17d142d..7e5da3be51 100644
--- a/satpy/readers/utils.py
+++ b/satpy/readers/utils.py
@@ -391,9 +391,10 @@ def get_earth_radius(lon, lat, a, b):
Earth Radius (meters)
"""
- geocent = pyproj.Proj(proj='geocent', a=a, b=b, units='m')
- latlong = pyproj.Proj(proj='latlong', a=a, b=b, units='m')
- x, y, z = pyproj.transform(latlong, geocent, lon, lat, 0.)
+ geocent = pyproj.CRS.from_dict({"proj": "geocent", "a": a, "b": b, "units": "m"})
+ latlong = pyproj.CRS.from_dict({"proj": "latlong", "a": a, "b": b, "units": "m"})
+ transformer = pyproj.Transformer.from_crs(latlong, geocent)
+ x, y, z = transformer.transform(lon, lat, 0.0)
return np.sqrt(x**2 + y**2 + z**2)
diff --git a/satpy/scene.py b/satpy/scene.py
index 7579b30a92..d43c9d80d2 100644
--- a/satpy/scene.py
+++ b/satpy/scene.py
@@ -1006,10 +1006,15 @@ def to_geoviews(self, gvtype=None, datasets=None, kdims=None, vdims=None, dynami
datasets (list): Limit included products to these datasets
kdims (list of str):
Key dimensions. See geoviews documentation for more information.
- vdims : list of str, optional
+ vdims (list of str, optional):
Value dimensions. See geoviews documentation for more information.
If not given defaults to first data variable
- dynamic : boolean, optional, default False
+ dynamic (bool, optional): Load and compute data on-the-fly during
+ visualization. Default is ``False``. See
+ https://holoviews.org/user_guide/Gridded_Datasets.html#working-with-xarray-data-types
+ for more information. Has no effect when data to be visualized
+ only has 2 dimensions (y/x or longitude/latitude) and doesn't
+ require grouping via the Holoviews ``groupby`` function.
Returns: geoviews object
@@ -1035,10 +1040,12 @@ def to_geoviews(self, gvtype=None, datasets=None, kdims=None, vdims=None, dynami
else:
gvds = gv.Dataset(ds)
+ # holoviews produces a log warning if you pass groupby arguments when groupby isn't used
+ groupby_kwargs = {"dynamic": dynamic} if gvds.ndims != 2 else {}
if "latitude" in ds.coords:
- gview = gvds.to(gv.QuadMesh, kdims=["longitude", "latitude"], vdims=vdims, dynamic=dynamic)
+ gview = gvds.to(gv.QuadMesh, kdims=["longitude", "latitude"], vdims=vdims, **groupby_kwargs)
else:
- gview = gvds.to(gvtype, kdims=["x", "y"], vdims=vdims, dynamic=dynamic)
+ gview = gvds.to(gvtype, kdims=["x", "y"], vdims=vdims, **groupby_kwargs)
return gview
diff --git a/satpy/tests/compositor_tests/test_spectral.py b/satpy/tests/compositor_tests/test_spectral.py
index 2e9f59c13f..467adf119b 100644
--- a/satpy/tests/compositor_tests/test_spectral.py
+++ b/satpy/tests/compositor_tests/test_spectral.py
@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License along with
# satpy. If not, see .
"""Tests for spectral correction compositors."""
+import warnings
import dask.array as da
import numpy as np
@@ -87,8 +88,10 @@ def test_ndvi_hybrid_green(self):
def test_green_corrector(self):
"""Test the deprecated class for green corrections."""
- comp = GreenCorrector('blended_channel', fractions=(0.85, 0.15), prerequisites=(0.51, 0.85),
- standard_name='toa_bidirectional_reflectance')
+ with warnings.catch_warnings():
+ warnings.filterwarnings("ignore", category=UserWarning, message=r'.*deprecated.*')
+ comp = GreenCorrector('blended_channel', fractions=(0.85, 0.15), prerequisites=(0.51, 0.85),
+ standard_name='toa_bidirectional_reflectance')
res = comp((self.c01, self.c03))
assert isinstance(res, xr.DataArray)
assert isinstance(res.data, da.Array)
diff --git a/satpy/tests/enhancement_tests/test_enhancements.py b/satpy/tests/enhancement_tests/test_enhancements.py
index 89ce222ecd..8cef879352 100644
--- a/satpy/tests/enhancement_tests/test_enhancements.py
+++ b/satpy/tests/enhancement_tests/test_enhancements.py
@@ -178,15 +178,6 @@ def test_three_d_effect(self):
[np.nan, np.nan, 85.5, 180.5, 1301.5]]])
run_and_check_enhancement(three_d_effect, self.ch1, expected)
- def test_crefl_scaling(self):
- """Test the crefl_scaling enhancement function."""
- from satpy.enhancements import crefl_scaling
- expected = np.array([[
- [np.nan, 0., 0., 0.44378, 0.631734],
- [0.737562, 0.825041, 0.912521, 1., 1.]]])
- run_and_check_enhancement(crefl_scaling, self.ch2, expected, idx=[0., 25., 55., 100., 255.],
- sc=[0., 90., 140., 175., 255.])
-
def test_piecewise_linear_stretch(self):
"""Test the piecewise_linear_stretch enhancement function."""
from satpy.enhancements import piecewise_linear_stretch
diff --git a/satpy/tests/multiscene_tests/test_utils.py b/satpy/tests/multiscene_tests/test_utils.py
index 22817d7629..409eb9cf86 100644
--- a/satpy/tests/multiscene_tests/test_utils.py
+++ b/satpy/tests/multiscene_tests/test_utils.py
@@ -62,18 +62,16 @@ def _fake_get_enhanced_image(img, enhance=None, overlay=None, decorate=None):
def _create_test_area(proj_str=None, shape=DEFAULT_SHAPE, extents=None):
"""Create a test area definition."""
- from pyresample.utils import proj4_str_to_dict
if proj_str is None:
proj_str = '+proj=lcc +datum=WGS84 +ellps=WGS84 +lon_0=-95. ' \
'+lat_0=25 +lat_1=25 +units=m +no_defs'
- proj_dict = proj4_str_to_dict(proj_str)
extents = extents or (-1000., -1500., 1000., 1500.)
return AreaDefinition(
'test',
'test',
'test',
- proj_dict,
+ proj_str,
shape[1],
shape[0],
extents
diff --git a/satpy/tests/reader_tests/test_satpy_cf_nc.py b/satpy/tests/reader_tests/test_satpy_cf_nc.py
index 52206e72b8..605f595e1f 100644
--- a/satpy/tests/reader_tests/test_satpy_cf_nc.py
+++ b/satpy/tests/reader_tests/test_satpy_cf_nc.py
@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License along with
# satpy. If not, see .
"""Tests for the CF reader."""
-
+import warnings
from datetime import datetime
import numpy as np
@@ -371,12 +371,14 @@ def test_read_prefixed_channels_by_user_include_prefix(self, _cf_scene, _nc_file
def test_read_prefixed_channels_by_user_no_prefix(self, _cf_scene, _nc_filename):
"""Check channels starting with digit is not prefixed by user."""
- _cf_scene.save_datasets(writer='cf',
- filename=_nc_filename,
- engine='netcdf4',
- flatten_attrs=True,
- pretty=True,
- numeric_name_prefix='')
+ with warnings.catch_warnings():
+ warnings.filterwarnings("ignore", category=UserWarning, message=".*starts with a digit.*")
+ _cf_scene.save_datasets(writer='cf',
+ filename=_nc_filename,
+ engine='netcdf4',
+ flatten_attrs=True,
+ pretty=True,
+ numeric_name_prefix='')
scn_ = Scene(reader='satpy_cf_nc',
filenames=[_nc_filename])
scn_.load(['1'])
diff --git a/satpy/tests/reader_tests/test_seviri_l1b_native.py b/satpy/tests/reader_tests/test_seviri_l1b_native.py
index 6bf5d2705d..a1a73179e2 100644
--- a/satpy/tests/reader_tests/test_seviri_l1b_native.py
+++ b/satpy/tests/reader_tests/test_seviri_l1b_native.py
@@ -21,6 +21,7 @@
import os
import unittest
+import warnings
from datetime import datetime
from unittest import mock
@@ -1279,7 +1280,8 @@ def test_satpos_no_valid_orbit_polynomial(self, file_handler):
'wavelength': (1, 2, 3),
'standard_name': 'counts'
}
- res = file_handler.get_dataset(dataset_id, dataset_info)
+ with pytest.warns(UserWarning, match="No orbit polynomial"):
+ res = file_handler.get_dataset(dataset_id, dataset_info)
assert 'satellite_actual_longitude' not in res.attrs[
'orbital_parameters']
@@ -1401,7 +1403,8 @@ def test_header_warning():
exp_warning = "The quality flag for this file indicates not OK. Use this data with caution!"
fromfile.return_value = header_good
- with pytest.warns(None):
+ with warnings.catch_warnings():
+ warnings.simplefilter("error")
NativeMSGFileHandler('myfile', {}, None)
fromfile.return_value = header_bad
diff --git a/satpy/tests/test_config.py b/satpy/tests/test_config.py
index e44a6a65e4..10d3205223 100644
--- a/satpy/tests/test_config.py
+++ b/satpy/tests/test_config.py
@@ -31,7 +31,7 @@
import satpy
from satpy import DatasetDict
-from satpy._config import cached_entry_points
+from satpy._config import cached_entry_point
from satpy.composites.config_loader import load_compositor_configs_for_sensors
# NOTE:
@@ -66,8 +66,7 @@ def test_areas_pyproj(self):
# we didn't provide enough info to freeze, hard to guess
# in a generic test so just skip this area
continue
- proj_dict = area_obj.proj_dict
- _ = pyproj.Proj(proj_dict)
+ _ = pyproj.Proj(area_obj.crs)
def test_areas_rasterio(self):
"""Test all areas have valid projections with rasterio."""
@@ -99,14 +98,7 @@ def test_areas_rasterio(self):
# we didn't provide enough info to freeze, hard to guess
# in a generic test so just skip this area
continue
- proj_dict = area_obj.proj_dict
- if proj_dict.get('proj') in ('ob_tran', 'nsper') and \
- 'wktext' not in proj_dict:
- # FIXME: rasterio doesn't understand ob_tran unless +wktext
- # See: https://github.com/pyproj4/pyproj/issues/357
- # pyproj 2.0+ seems to drop wktext from PROJ dict
- continue
- _ = CRS.from_dict(proj_dict)
+ _ = CRS.from_user_input(area_obj.crs)
@contextlib.contextmanager
@@ -299,7 +291,7 @@ class TestPluginsConfigs:
def setup_method(self):
"""Set up the test."""
- cached_entry_points.cache_clear()
+ cached_entry_point.cache_clear()
def test_get_plugin_configs(self, fake_composite_plugin_etc_path):
"""Check that the plugin configs are looked for."""