From adde5c16722bfe2384d6eb182e0509082b3e2faf Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 09:32:49 -0500 Subject: [PATCH 01/22] Fix scipy 1.14 compatibility and trapz usage --- pyspectral/radiance_tb_conversion.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pyspectral/radiance_tb_conversion.py b/pyspectral/radiance_tb_conversion.py index ca6a2f5..8521b8e 100644 --- a/pyspectral/radiance_tb_conversion.py +++ b/pyspectral/radiance_tb_conversion.py @@ -28,12 +28,16 @@ from numbers import Number import numpy as np -from scipy import integrate from pyspectral.blackbody import C_SPEED, H_PLANCK, K_BOLTZMANN, blackbody, blackbody_wn from pyspectral.rsr_reader import RelativeSpectralResponse from pyspectral.utils import BANDNAMES, WAVE_LENGTH, WAVE_NUMBER, convert2wavenumber, get_bandname_from_wavelength +try: + from scipy.integrate import trapezoid +except ImportError: + from scipy.integrate import trapz as trapezoid + LOG = logging.getLogger(__name__) BLACKBODY_FUNC = {WAVE_LENGTH: blackbody, @@ -221,9 +225,9 @@ def tb2radiance(self, tb_, **kwargs): planck = self.blackbody_function(self.wavelength_or_wavenumber, tb_) * self.response if normalized: - radiance = integrate.trapz(planck, self.wavelength_or_wavenumber) / self.rsr_integral + radiance = trapezoid(planck, self.wavelength_or_wavenumber) / self.rsr_integral else: - radiance = integrate.trapz(planck, self.wavelength_or_wavenumber) + radiance = trapezoid(planck, self.wavelength_or_wavenumber) return {'radiance': radiance, 'unit': unit, From 41265c79eceadc0dccf18ba0f4ea9a48442b1d10 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 09:48:43 -0500 Subject: [PATCH 02/22] Replace legacy np.string_ usage with np.bytes_ --- pyspectral/tests/test_utils.py | 12 ++++++------ pyspectral/utils.py | 9 ++++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pyspectral/tests/test_utils.py b/pyspectral/tests/test_utils.py index 3969bc0..c54bd8d 100644 --- a/pyspectral/tests/test_utils.py +++ b/pyspectral/tests/test_utils.py @@ -225,11 +225,11 @@ def test_get_wave_range(self): @pytest.mark.parametrize( ("input_value", "exp_except"), [ - (np.string_("hey"), False), - (np.array([np.string_("hey")]), False), - (np.array(np.string_("hey")), False), + (np.bytes_("hey"), False), + (np.array([np.bytes_("hey")]), False), + (np.array(np.bytes_("hey")), False), ("hey", False), - (np.array([np.string_("hey"), np.string_("hey")]), True), + (np.array([np.bytes_("hey"), np.bytes_("hey")]), True), (5, True), ], ) @@ -247,8 +247,8 @@ def test_np2str(input_value, exp_except): [ (b"Hello", "Hello"), ("Hello", "Hello"), - (np.string_("Hello"), "Hello"), - (np.array(np.string_("Hello")), np.array(np.string_("Hello"))), + (np.bytes_("Hello"), "Hello"), + (np.array(np.bytes_("Hello")), np.array(np.bytes_("Hello"))), ] ) def test_bytes2string(input_value, exp_result): diff --git a/pyspectral/utils.py b/pyspectral/utils.py index 425db6d..2c1b002 100644 --- a/pyspectral/utils.py +++ b/pyspectral/utils.py @@ -506,20 +506,23 @@ def convert2str(value): def np2str(value): - """Convert an `numpy.string_` to str. + """Convert an ``numpy.bytes_`` to str. + + Note: ``numpy.string_`` was deprecated in numpy 2.0 in favor of + ``numpy.bytes_``. Args: value (ndarray): scalar or 1-element numpy array to convert Raises: ValueError: if value is array larger than 1-element or it is not of - type `numpy.string_` or it is not a numpy array + type `numpy.bytes_` or it is not a numpy array """ if isinstance(value, str): return value if hasattr(value, 'dtype') and \ - issubclass(value.dtype.type, (np.str_, np.string_, np.object_)) \ + issubclass(value.dtype.type, (np.str_, np.bytes_, np.object_)) \ and value.size == 1: value = value.item() # python 3 - was scalar numpy array of bytes From 5c4508f155188cdb85648c329b7ce7e628487782 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 10:18:51 -0500 Subject: [PATCH 03/22] Fix blackbody upcasting input radiances with float64 wavelength Numpy 2 used np.float64 wavelength as reason to upcast. --- pyspectral/blackbody.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyspectral/blackbody.py b/pyspectral/blackbody.py index a684684..901a835 100644 --- a/pyspectral/blackbody.py +++ b/pyspectral/blackbody.py @@ -54,6 +54,9 @@ def blackbody_rad2temp(wavelength, radiance): The derived temperature in Kelvin. """ + if getattr(wavelength, "dtype", None) != radiance.dtype: + # avoid a wavelength numpy scalar upcasting radiances (ex. 32-bit to 64-bit float) + wavelength = radiance.dtype.type(wavelength) with np.errstate(invalid='ignore'): return PLANCK_C1 / (wavelength * np.log(PLANCK_C2 / (radiance * wavelength**5) + 1.0)) From 5b4e7556d184bdb3be36a1063b58491b57d5c6a9 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 10:19:07 -0500 Subject: [PATCH 04/22] Fix dtype usage in numpy rayleigh test --- pyspectral/tests/test_rayleigh.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/pyspectral/tests/test_rayleigh.py b/pyspectral/tests/test_rayleigh.py index f11dbe5..8da5199 100644 --- a/pyspectral/tests/test_rayleigh.py +++ b/pyspectral/tests/test_rayleigh.py @@ -184,25 +184,26 @@ def test_get_reflectance_dask(self, fake_lut_hdf5, dtype): assert refl_corr.dtype == dtype # check that the dask array's dtype is equal assert refl_corr.compute().dtype == dtype # check that the final numpy array's dtype is equal - def test_get_reflectance_numpy_dask(self, fake_lut_hdf5): + @pytest.mark.parametrize("dtype", [np.float32, np.float64]) + def test_get_reflectance_numpy(self, fake_lut_hdf5, dtype): """Test getting the reflectance correction with dask inputs.""" - sun_zenith = np.array([67., 32.]) - sat_zenith = np.array([45., 18.]) - azidiff = np.array([150., 110.]) - redband_refl = np.array([14., 5.]) + sun_zenith = np.array([67., 32.], dtype=dtype) + sat_zenith = np.array([45., 18.], dtype=dtype) + azidiff = np.array([150., 110.], dtype=dtype) + redband_refl = np.array([14., 5.], dtype=dtype) rayl = _create_rayleigh() with mocked_rsr(): refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) - np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT1) + np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT1.astype(dtype), atol=4.0e-06) assert isinstance(refl_corr, np.ndarray) - sun_zenith = np.array([60., 20.]) - sat_zenith = np.array([49., 26.]) - azidiff = np.array([140., 130.]) - redband_refl = np.array([12., 8.]) + sun_zenith = np.array([60., 20.], dtype=dtype) + sat_zenith = np.array([49., 26.], dtype=dtype) + azidiff = np.array([140., 130.], dtype=dtype) + redband_refl = np.array([12., 8.], dtype=dtype) with mocked_rsr(): refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) - np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT2) + np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT2.astype(dtype), atol=4.0e-06) assert isinstance(refl_corr, np.ndarray) def test_get_reflectance_wvl_outside_range(self, fake_lut_hdf5): @@ -354,6 +355,7 @@ def test_get_reflectance(self, fake_lut_hdf5, sun_zenith, sat_zenith, azidiff, r refl_corr = rayl.get_reflectance( sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) assert isinstance(refl_corr, np.ndarray) + print(refl_corr.dtype) np.testing.assert_allclose(refl_corr, exp_result) @patch('pyspectral.rayleigh.da', None) From 8d32f34a63f255199a84902debd071ebb99a8a07 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 10:26:27 -0500 Subject: [PATCH 05/22] Add better parametrize in rayleigh test --- pyspectral/tests/test_rayleigh.py | 62 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/pyspectral/tests/test_rayleigh.py b/pyspectral/tests/test_rayleigh.py index 8da5199..2b96f0f 100644 --- a/pyspectral/tests/test_rayleigh.py +++ b/pyspectral/tests/test_rayleigh.py @@ -136,6 +136,10 @@ def mocked_rsr(): yield mymock +def _create_dask_array(input_data, dtype): + return da.from_array(np.array(input_data, dtype=dtype)) + + class TestRayleighDask: """Class for testing pyspectral.rayleigh - with dask-arrays as input.""" @@ -159,52 +163,44 @@ def test_get_reflectance_dask_redband_outside_clip(self, fake_lut_hdf5): assert isinstance(refl_corr, da.Array) @pytest.mark.parametrize("dtype", [np.float32, np.float64]) - def test_get_reflectance_dask(self, fake_lut_hdf5, dtype): + @pytest.mark.parametrize("use_dask", [False, True]) + def test_get_reflectance(self, fake_lut_hdf5, dtype, use_dask): """Test getting the reflectance correction with dask inputs.""" - sun_zenith = da.array([67., 32.], dtype=dtype) - sat_zenith = da.array([45., 18.], dtype=dtype) - azidiff = da.array([150., 110.], dtype=dtype) - redband_refl = da.array([14., 5.], dtype=dtype) + array_func = np.array if not use_dask else _create_dask_array + sun_zenith = array_func([67., 32.], dtype=dtype) + sat_zenith = array_func([45., 18.], dtype=dtype) + azidiff = array_func([150., 110.], dtype=dtype) + redband_refl = array_func([14., 5.], dtype=dtype) rayl = _create_rayleigh() with mocked_rsr(): refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) + + if use_dask: + assert isinstance(refl_corr, da.Array) + refl_corr_np = refl_corr.compute() + assert refl_corr_np.dtype == refl_corr.dtype # check that the final numpy array's dtype is equal + refl_corr = refl_corr_np + + assert isinstance(refl_corr, np.ndarray) np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT1.astype(dtype), atol=4.0e-06) - assert isinstance(refl_corr, da.Array) assert refl_corr.dtype == dtype # check that the dask array's dtype is equal - assert refl_corr.compute().dtype == dtype # check that the final numpy array's dtype is equal - sun_zenith = da.array([60., 20.], dtype=dtype) - sat_zenith = da.array([49., 26.], dtype=dtype) - azidiff = da.array([140., 130.], dtype=dtype) - redband_refl = da.array([12., 8.], dtype=dtype) + sun_zenith = array_func([60., 20.], dtype=dtype) + sat_zenith = array_func([49., 26.], dtype=dtype) + azidiff = array_func([140., 130.], dtype=dtype) + redband_refl = array_func([12., 8.], dtype=dtype) with mocked_rsr(): refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) - np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT2.astype(dtype), atol=4.0e-06) - assert isinstance(refl_corr, da.Array) - assert refl_corr.dtype == dtype # check that the dask array's dtype is equal - assert refl_corr.compute().dtype == dtype # check that the final numpy array's dtype is equal - @pytest.mark.parametrize("dtype", [np.float32, np.float64]) - def test_get_reflectance_numpy(self, fake_lut_hdf5, dtype): - """Test getting the reflectance correction with dask inputs.""" - sun_zenith = np.array([67., 32.], dtype=dtype) - sat_zenith = np.array([45., 18.], dtype=dtype) - azidiff = np.array([150., 110.], dtype=dtype) - redband_refl = np.array([14., 5.], dtype=dtype) - rayl = _create_rayleigh() - with mocked_rsr(): - refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) - np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT1.astype(dtype), atol=4.0e-06) - assert isinstance(refl_corr, np.ndarray) + if use_dask: + assert isinstance(refl_corr, da.Array) + refl_corr_np = refl_corr.compute() + assert refl_corr_np.dtype == refl_corr.dtype # check that the final numpy array's dtype is equal + refl_corr = refl_corr_np - sun_zenith = np.array([60., 20.], dtype=dtype) - sat_zenith = np.array([49., 26.], dtype=dtype) - azidiff = np.array([140., 130.], dtype=dtype) - redband_refl = np.array([12., 8.], dtype=dtype) - with mocked_rsr(): - refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT2.astype(dtype), atol=4.0e-06) assert isinstance(refl_corr, np.ndarray) + assert refl_corr.dtype == dtype # check that the dask array's dtype is equal def test_get_reflectance_wvl_outside_range(self, fake_lut_hdf5): """Test getting the reflectance correction with wavelength outside correction range.""" From fedaed8411f048c8f6b3a38e083ee3b27a6bd3d7 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 10:29:12 -0500 Subject: [PATCH 06/22] More parametrization in rayleigh tests --- pyspectral/tests/test_rayleigh.py | 36 +++++++++++-------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/pyspectral/tests/test_rayleigh.py b/pyspectral/tests/test_rayleigh.py index 2b96f0f..c6b97ea 100644 --- a/pyspectral/tests/test_rayleigh.py +++ b/pyspectral/tests/test_rayleigh.py @@ -164,13 +164,20 @@ def test_get_reflectance_dask_redband_outside_clip(self, fake_lut_hdf5): @pytest.mark.parametrize("dtype", [np.float32, np.float64]) @pytest.mark.parametrize("use_dask", [False, True]) - def test_get_reflectance(self, fake_lut_hdf5, dtype, use_dask): + @pytest.mark.parametrize( + ("input_data", "exp_result"), + [ + (([67.0, 32.0], [45.0, 18.0], [150.0, 110.0], [14.0, 5.0]), TEST_RAYLEIGH_RESULT1), + (([60.0, 20.0], [49.0, 26.0], [140.0, 130.0], [12.0, 8.0]), TEST_RAYLEIGH_RESULT2), + ] + ) + def test_get_reflectance(self, fake_lut_hdf5, dtype, use_dask, input_data, exp_result): """Test getting the reflectance correction with dask inputs.""" array_func = np.array if not use_dask else _create_dask_array - sun_zenith = array_func([67., 32.], dtype=dtype) - sat_zenith = array_func([45., 18.], dtype=dtype) - azidiff = array_func([150., 110.], dtype=dtype) - redband_refl = array_func([14., 5.], dtype=dtype) + sun_zenith = array_func(input_data[0], dtype=dtype) + sat_zenith = array_func(input_data[1], dtype=dtype) + azidiff = array_func(input_data[2], dtype=dtype) + redband_refl = array_func(input_data[3], dtype=dtype) rayl = _create_rayleigh() with mocked_rsr(): refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) @@ -182,24 +189,7 @@ def test_get_reflectance(self, fake_lut_hdf5, dtype, use_dask): refl_corr = refl_corr_np assert isinstance(refl_corr, np.ndarray) - np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT1.astype(dtype), atol=4.0e-06) - assert refl_corr.dtype == dtype # check that the dask array's dtype is equal - - sun_zenith = array_func([60., 20.], dtype=dtype) - sat_zenith = array_func([49., 26.], dtype=dtype) - azidiff = array_func([140., 130.], dtype=dtype) - redband_refl = array_func([12., 8.], dtype=dtype) - with mocked_rsr(): - refl_corr = rayl.get_reflectance(sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) - - if use_dask: - assert isinstance(refl_corr, da.Array) - refl_corr_np = refl_corr.compute() - assert refl_corr_np.dtype == refl_corr.dtype # check that the final numpy array's dtype is equal - refl_corr = refl_corr_np - - np.testing.assert_allclose(refl_corr, TEST_RAYLEIGH_RESULT2.astype(dtype), atol=4.0e-06) - assert isinstance(refl_corr, np.ndarray) + np.testing.assert_allclose(refl_corr, exp_result.astype(dtype), atol=4.0e-06) assert refl_corr.dtype == dtype # check that the dask array's dtype is equal def test_get_reflectance_wvl_outside_range(self, fake_lut_hdf5): From 3152387c4e54eabd51680cdd474c78433845469e Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 10:43:35 -0500 Subject: [PATCH 07/22] Fix more dtype handling in rayleigh tests --- pyspectral/tests/test_rayleigh.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pyspectral/tests/test_rayleigh.py b/pyspectral/tests/test_rayleigh.py index c6b97ea..ec8ca80 100644 --- a/pyspectral/tests/test_rayleigh.py +++ b/pyspectral/tests/test_rayleigh.py @@ -334,15 +334,19 @@ def test_get_reflectance_redband_outside_clip(self, fake_lut_hdf5): TEST_RAYLEIGH_RESULT5), ] ) - def test_get_reflectance(self, fake_lut_hdf5, sun_zenith, sat_zenith, azidiff, redband_refl, exp_result): + @pytest.mark.parametrize("dtype", [np.float32, np.float64]) + def test_get_reflectance(self, fake_lut_hdf5, sun_zenith, sat_zenith, azidiff, redband_refl, exp_result, dtype): """Test getting the reflectance correction.""" rayl = _create_rayleigh() with mocked_rsr(): refl_corr = rayl.get_reflectance( - sun_zenith, sat_zenith, azidiff, 'ch3', redband_refl) + sun_zenith.astype(dtype), + sat_zenith.astype(dtype), + azidiff.astype(dtype), + 'ch3', + redband_refl.astype(dtype)) assert isinstance(refl_corr, np.ndarray) - print(refl_corr.dtype) - np.testing.assert_allclose(refl_corr, exp_result) + np.testing.assert_allclose(refl_corr, exp_result.astype(dtype), atol=4.0e-06) @patch('pyspectral.rayleigh.da', None) def test_get_reflectance_no_rsr(self, fake_lut_hdf5): From 239c410622ea0472c5f19f2745bde25b72c5dbf4 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 10:44:03 -0500 Subject: [PATCH 08/22] Fix solar_flux 64-bit float causing upcasting in NIR reflectance calculations --- pyspectral/near_infrared_reflectance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyspectral/near_infrared_reflectance.py b/pyspectral/near_infrared_reflectance.py index 1c86ce2..807b2a9 100644 --- a/pyspectral/near_infrared_reflectance.py +++ b/pyspectral/near_infrared_reflectance.py @@ -259,7 +259,7 @@ def reflectance_from_tbs(self, sun_zenith, tb_near_ir, tb_thermal, **kwargs): mu0 = np.cos(np.deg2rad(sunz)) # mu0 = np.where(np.less(mu0, 0.1), 0.1, mu0) - self._solar_radiance = self.solar_flux * mu0 / np.pi + self._solar_radiance = (self.solar_flux * mu0 / np.pi).astype(tb_nir.dtype) # CO2 correction to the 3.9 radiance, only if tbs of a co2 band around # 13.4 micron is provided: From a546b8d2f8329489fc1152698ac6419742664ee9 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 27 Jun 2024 21:23:44 -0500 Subject: [PATCH 09/22] Update release notes for 0.13.2 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff0278e..24d5c46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +## Version <0.13.2> (2024/06/27) + +### Issues Closed + +* [Issue 227](https://github.com/pytroll/pyspectral/issues/227) - Pyspectral 0.13.1 not compatible with SciPy 1.14.x -> update dependencies ([PR 228](https://github.com/pytroll/pyspectral/pull/228) by [@djhoese](https://github.com/djhoese)) + +In this release 1 issue was closed. + +### Pull Requests Merged + +#### Bugs fixed + +* [PR 228](https://github.com/pytroll/pyspectral/pull/228) - Fix scipy 1.14 compatibility and trapz usage ([227](https://github.com/pytroll/pyspectral/issues/227)) + +In this release 1 pull request was closed. + + ## Version (2024/05/07) ### Issues Closed From 5d126121ef1e59caf1f7cbbccb0c71132c774ac1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 00:39:00 +0000 Subject: [PATCH 10/22] Bump pypa/gh-action-pypi-publish from 1.8.14 to 1.9.0 Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.14 to 1.9.0. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.14...v1.9.0) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy-sdist.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-sdist.yaml b/.github/workflows/deploy-sdist.yaml index 6353644..1c476eb 100644 --- a/.github/workflows/deploy-sdist.yaml +++ b/.github/workflows/deploy-sdist.yaml @@ -23,7 +23,7 @@ jobs: - name: Publish package to PyPI if: github.event.action == 'published' - uses: pypa/gh-action-pypi-publish@v1.8.14 + uses: pypa/gh-action-pypi-publish@v1.9.0 with: user: __token__ password: ${{ secrets.pypi_password }} From 102a19f868a35c363fc6e1da27bdafb8bbac4238 Mon Sep 17 00:00:00 2001 From: "Adam.Dybbroe" Date: Mon, 15 Jul 2024 11:21:59 +0200 Subject: [PATCH 11/22] Update link to latest RSR on Zenodo Signed-off-by: Adam.Dybbroe --- pyspectral/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyspectral/utils.py b/pyspectral/utils.py index 0c08446..f993d7e 100644 --- a/pyspectral/utils.py +++ b/pyspectral/utils.py @@ -105,10 +105,10 @@ 'avhrr-2': 'avhrr/2', 'avhrr-3': 'avhrr/3'} -HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/11110033/files/pyspectral_rsr_data.tgz" +HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/12742887/files/pyspectral_rsr_data.tgz" RSR_DATA_VERSION_FILENAME = "PYSPECTRAL_RSR_VERSION" -RSR_DATA_VERSION = "v1.3.0" +RSR_DATA_VERSION = "v1.3.1" ATM_CORRECTION_LUT_VERSION = {} ATM_CORRECTION_LUT_VERSION['antarctic_aerosol'] = {'version': 'v1.0.1', From 29663bccb0521d57bf81a97baeb00133c4142721 Mon Sep 17 00:00:00 2001 From: "Adam.Dybbroe" Date: Mon, 15 Jul 2024 12:37:53 +0200 Subject: [PATCH 12/22] Updated the file name for the FY-3F Mersi-3 RSRs Signed-off-by: Adam.Dybbroe --- pyspectral/rsr_reader.py | 2 +- pyspectral/utils.py | 4 ++-- rsr_convert_scripts/mersi3_rsr.py | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pyspectral/rsr_reader.py b/pyspectral/rsr_reader.py index ff3020b..bbc2d69 100644 --- a/pyspectral/rsr_reader.py +++ b/pyspectral/rsr_reader.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright (c) 2014-2022 Pytroll developers +# Copyright (c) 2014-2024 Pytroll developers # # # This program is free software: you can redistribute it and/or modify diff --git a/pyspectral/utils.py b/pyspectral/utils.py index f993d7e..38f54e2 100644 --- a/pyspectral/utils.py +++ b/pyspectral/utils.py @@ -105,10 +105,10 @@ 'avhrr-2': 'avhrr/2', 'avhrr-3': 'avhrr/3'} -HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/12742887/files/pyspectral_rsr_data.tgz" +HTTP_PYSPECTRAL_RSR = "https://zenodo.org/records/12743289/files/pyspectral_rsr_data.tgz" RSR_DATA_VERSION_FILENAME = "PYSPECTRAL_RSR_VERSION" -RSR_DATA_VERSION = "v1.3.1" +RSR_DATA_VERSION = "v1.3.2" ATM_CORRECTION_LUT_VERSION = {} ATM_CORRECTION_LUT_VERSION['antarctic_aerosol'] = {'version': 'v1.0.1', diff --git a/rsr_convert_scripts/mersi3_rsr.py b/rsr_convert_scripts/mersi3_rsr.py index 45856f2..5b3b882 100644 --- a/rsr_convert_scripts/mersi3_rsr.py +++ b/rsr_convert_scripts/mersi3_rsr.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright (c) 2018-2022 Pytroll developers +# Copyright (c) 2018-2022, 2024 Pytroll developers # # # This program is free software: you can redistribute it and/or modify @@ -28,7 +28,6 @@ import numpy as np from pyspectral.raw_reader import InstrumentRSR -from pyspectral.utils import INSTRUMENTS from pyspectral.utils import convert2hdf5 as tohdf5 LOG = logging.getLogger(__name__) @@ -43,10 +42,10 @@ class Mersi3RSR(InstrumentRSR): """Container for the FY3D MERSI-II RSR data.""" def __init__(self, bandname, platform_name): - """Initialize the MERSI-2 RSR class.""" + """Initialize the MERSI-3 RSR class.""" super(Mersi3RSR, self).__init__(bandname, platform_name, MERSI3_BAND_NAMES) - self.instrument = INSTRUMENTS.get(platform_name, 'mersi-3') + self.instrument = 'mersi3' self._get_options_from_config() self._get_bandfilenames() From 6c34706c72436378b58eebd8ab79604fe38b578f Mon Sep 17 00:00:00 2001 From: "Adam.Dybbroe" Date: Wed, 17 Jul 2024 10:52:12 +0200 Subject: [PATCH 13/22] Update the change log and pretify the version section headers Signed-off-by: Adam.Dybbroe --- CHANGELOG.md | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24d5c46..200a0ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,19 @@ -## Version <0.13.2> (2024/06/27) +## Version v0.13.3 (2024/07/17) + +### Pull Requests Merged + +#### Bugs fixed + +* [PR 231](https://github.com/pytroll/pyspectral/pull/231) - Updated the file name for the FY-3F Mersi-3 RSRs + +#### Features added + +* [PR 226](https://github.com/pytroll/pyspectral/pull/226) - Add RSR script for MERSI-3 onboard FY-3F + +In this release 2 pull requests were closed. + + +## Version v0.13.2 (2024/06/27) ### Issues Closed @@ -15,7 +30,7 @@ In this release 1 issue was closed. In this release 1 pull request was closed. -## Version (2024/05/07) +## Version v0.13.1 (2024/05/07) ### Issues Closed @@ -37,7 +52,7 @@ In this release 2 issues were closed. In this release 5 pull requests were closed. -## Version (2023/11/27) +## Version v0.13.0 (2023/11/27) ### Issues Closed @@ -60,7 +75,7 @@ In this release 2 issues were closed. In this release 6 pull requests were closed. -## Version (2023/09/21) +## Version 0.12.5 (2023/09/21) ### Pull Requests Merged @@ -71,7 +86,7 @@ In this release 6 pull requests were closed. In this release 1 pull request was closed. -## Version (2023/09/20) +## Version v0.12.4 (2023/09/20) ### Issues Closed @@ -93,7 +108,7 @@ In this release 1 issue was closed. In this release 3 pull requests were closed. -## Version (2022/11/22) +## Version v0.12.3 (2022/11/22) ### Issues Closed @@ -119,7 +134,7 @@ In this release 5 issues were closed. In this release 3 pull requests were closed. -## Version (2022/10/24) +## Version 0.12.2 (2022/10/24) ### Issues Closed @@ -136,7 +151,7 @@ In this release 1 issue was closed. In this release 1 pull request was closed. -## Version (2022/10/20) +## Version v0.12.1 (2022/10/20) ### Pull Requests Merged @@ -152,7 +167,7 @@ In this release 1 pull request was closed. In this release 2 pull requests were closed. -## Version (2022/10/11) +## Version v0.12.0 (2022/10/11) ### Issues Closed @@ -187,7 +202,7 @@ In this release 1 issue was closed. In this release 13 pull requests were closed. -## Version (2022/03/01) +## Version v0.11.0 (2022/03/01) ### Pull Requests Merged @@ -200,7 +215,7 @@ In this release 13 pull requests were closed. In this release 2 pull requests were closed. -## Version (2021/12/22) +## Version v0.10.6 (2021/12/22) ### Issues Closed @@ -226,7 +241,7 @@ In this release 2 issues were closed. In this release 6 pull requests were closed. -## Version (2021/04/29) +## Version v0.10.5 (2021/04/29) ### Pull Requests Merged @@ -245,7 +260,7 @@ In this release 6 pull requests were closed. In this release 2 pull requests were closed. -## Version (2020/12/07) +## Version v0.10.4 (2020/12/07) ### Pull Requests Merged @@ -257,7 +272,7 @@ In this release 2 pull requests were closed. In this release 1 pull request was closed. -## Version (2020/12/04) +## Version v0.10.3 (2020/12/04) ### Issues Closed @@ -265,7 +280,8 @@ In this release 1 pull request was closed. In this release 1 issue was closed. -## Version (2020/11/20) + +## Version v0.10.2 (2020/11/20) ### Issues Closed @@ -296,7 +312,7 @@ In this release 1 issue was closed. In this release 9 pull requests were closed. -## Version (2020/10/06) +## Version v0.10.1 (2020/10/06) ### Issues Closed From 57a94bd26b082386756925d00293c9f776ecbb7d Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 18 Jul 2024 09:14:27 -0500 Subject: [PATCH 14/22] Remove unused requirements.txt --- requirements.txt | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 30be043..0000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -python-geotiepoints>=1.1.1 -numpy>=1.5.1 -scipy>=0.14 -h5py>=2.5 -six From 17aa1fbf440b2250db6cb514181af575e7c8852e Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 18 Jul 2024 09:34:41 -0500 Subject: [PATCH 15/22] Remove unused and deprecated setup.py code --- pyspectral/tests/__init__.py | 42 +++--------------------------------- setup.py | 11 +++------- 2 files changed, 6 insertions(+), 47 deletions(-) diff --git a/pyspectral/tests/__init__.py b/pyspectral/tests/__init__.py index 4688c7d..b6039d7 100644 --- a/pyspectral/tests/__init__.py +++ b/pyspectral/tests/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - +# # Copyright (c) 2013-2022 Pytroll Developers # # @@ -8,48 +8,12 @@ # 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. - +# # This program 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 this program. If not, see . - """The tests package.""" - -import doctest -import os -import sys - -from pyspectral import blackbody, near_infrared_reflectance, solar - -if sys.version_info < (2, 7): - import unittest2 as unittest -else: - import unittest - -TRAVIS = os.environ.get("TRAVIS", False) -APPVEYOR = os.environ.get("APPVEYOR", False) - - -def suite(): - """Perform the unit testing.""" - mysuite = unittest.TestSuite() - if not TRAVIS and not APPVEYOR: - # Test sphinx documentation pages: - mysuite.addTests(doctest.DocFileSuite('../../doc/usage.rst')) - mysuite.addTests(doctest.DocFileSuite('../../doc/rad_definitions.rst')) - # mysuite.addTests(doctest.DocFileSuite('../../doc/seviri_example.rst')) - mysuite.addTests(doctest.DocFileSuite('../../doc/37_reflectance.rst')) - # Test the documentation strings - mysuite.addTests(doctest.DocTestSuite(solar)) - mysuite.addTests(doctest.DocTestSuite(near_infrared_reflectance)) - mysuite.addTests(doctest.DocTestSuite(blackbody)) - - return mysuite - - -if __name__ == '__main__': - unittest.TextTestRunner(verbosity=2).run(suite()) diff --git a/setup.py b/setup.py index 7b5f009..f68b052 100644 --- a/setup.py +++ b/setup.py @@ -26,13 +26,10 @@ description = ('Reading and manipulaing satellite sensor spectral responses and the ' 'solar spectrum, to perfom various corrections to VIS and NIR band data') -try: - with open('./README.md', 'r') as fd: - long_description = fd.read() -except IOError: - long_description = '' +with open('./README.md', 'r') as fd: + long_description = fd.read() -requires = ['docutils>=0.3', 'numpy', 'scipy', 'python-geotiepoints>=1.1.1', +requires = ['numpy', 'scipy', 'python-geotiepoints>=1.1.1', 'h5py>=2.5', 'requests', 'pyyaml', 'platformdirs'] dask_extra = ['dask[array]'] @@ -80,8 +77,6 @@ 'bin/download_rsr.py'], data_files=[('share', ['pyspectral/data/e490_00a.dat', 'pyspectral/data/MSG_SEVIRI_Spectral_Response_Characterisation.XLS'])], - test_suite='pyspectral.tests.suite', - tests_require=test_requires, python_requires='>=3.10', zip_safe=False, ) From 85ee9bebff4341d425ba9f362e2dc387f9b58ab7 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 18 Jul 2024 09:36:46 -0500 Subject: [PATCH 16/22] Add test deps as a 'test' extra --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index f68b052..f16e2e3 100644 --- a/setup.py +++ b/setup.py @@ -71,6 +71,7 @@ 'matplotlib': ['matplotlib'], 'pandas': ['pandas'], 'tqdm': ['tqdm'], + 'test': test_requires, 'dask': dask_extra}, scripts=['bin/plot_rsr.py', 'bin/composite_rsr_plot.py', 'bin/download_atm_correction_luts.py', From 28dceac3d083d3d8a8635514b7ce5d734eee0001 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Thu, 18 Jul 2024 09:37:26 -0500 Subject: [PATCH 17/22] Remove unused RTD requirements file --- doc/rtd_requirements.txt | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 doc/rtd_requirements.txt diff --git a/doc/rtd_requirements.txt b/doc/rtd_requirements.txt deleted file mode 100644 index 7c7729e..0000000 --- a/doc/rtd_requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -python-geotiepoints>=1.1.1 -numpy>=1.22.2 -scipy>=0.14 -h5py>=2.5 -six -requests -tqdm -pyyaml -xlrd -git-lfs From 2a5e5aa985d67b90454d528526fe090f2a0984d2 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Fri, 19 Jul 2024 14:11:49 -0500 Subject: [PATCH 18/22] Fix various numpy and python deprecations --- pyspectral/_compat.py | 5 +++++ pyspectral/radiance_tb_conversion.py | 3 ++- pyspectral/rsr_reader.py | 5 ++--- pyspectral/solar.py | 10 ++++++---- pyspectral/utils.py | 7 +++++-- 5 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 pyspectral/_compat.py diff --git a/pyspectral/_compat.py b/pyspectral/_compat.py new file mode 100644 index 0000000..21271da --- /dev/null +++ b/pyspectral/_compat.py @@ -0,0 +1,5 @@ +"""Various helpers for backwards and forwards compatibility.""" + +import numpy as np + +np_trapezoid = np.trapezoid if hasattr(np, "trapezoid") else np.trapz diff --git a/pyspectral/radiance_tb_conversion.py b/pyspectral/radiance_tb_conversion.py index 8521b8e..8b0b10c 100644 --- a/pyspectral/radiance_tb_conversion.py +++ b/pyspectral/radiance_tb_conversion.py @@ -29,6 +29,7 @@ import numpy as np +from pyspectral._compat import np_trapezoid from pyspectral.blackbody import C_SPEED, H_PLANCK, K_BOLTZMANN, blackbody, blackbody_wn from pyspectral.rsr_reader import RelativeSpectralResponse from pyspectral.utils import BANDNAMES, WAVE_LENGTH, WAVE_NUMBER, convert2wavenumber, get_bandname_from_wavelength @@ -159,7 +160,7 @@ def _get_rsr(self): self._wave_si_scale) self.response = self.rsr[self.bandname][self.detector]['response'] # Get the integral of the spectral response curve: - self.rsr_integral = np.trapz(self.response, self.wavelength_or_wavenumber) + self.rsr_integral = np_trapezoid(self.response, self.wavelength_or_wavenumber) def _getsatname(self): """Get the satellite name used in the rsr-reader, from the platform and number.""" diff --git a/pyspectral/rsr_reader.py b/pyspectral/rsr_reader.py index bbc2d69..50eea61 100644 --- a/pyspectral/rsr_reader.py +++ b/pyspectral/rsr_reader.py @@ -24,8 +24,7 @@ from glob import glob from os.path import expanduser -import numpy as np - +from pyspectral._compat import np_trapezoid from pyspectral.bandnames import BANDNAMES from pyspectral.config import get_config from pyspectral.utils import ( @@ -214,7 +213,7 @@ def integral(self, bandname): for det in self.rsr[bandname].keys(): wvl = self.rsr[bandname][det]['wavelength'] resp = self.rsr[bandname][det]['response'] - intg[det] = np.trapz(resp, wvl) + intg[det] = np_trapezoid(resp, wvl) return intg def convert(self): diff --git a/pyspectral/solar.py b/pyspectral/solar.py index 0cb30f5..e13e8f0 100644 --- a/pyspectral/solar.py +++ b/pyspectral/solar.py @@ -30,6 +30,8 @@ import numpy as np +from pyspectral._compat import np_trapezoid + LOG = logging.getLogger(__name__) # STANDARD SPECTRA from Air Mass Zero: http://rredc.nrel.gov/solar/spectra/am0/ @@ -121,9 +123,9 @@ def _load(self): def solar_constant(self): """Calculate the solar constant.""" if self.wavenumber is not None: - return np.trapz(self.irradiance, self.wavenumber) + return np_trapezoid(self.irradiance, self.wavenumber) if self.wavelength is not None: - return np.trapz(self.irradiance, self.wavelength) + return np_trapezoid(self.irradiance, self.wavelength) raise TypeError('Neither wavelengths nor wavenumbers available!') @@ -204,10 +206,10 @@ def _band_calculations(self, rsr, flux, scale, **options): # Calculate the solar-flux: (w/m2) if flux: - return np.trapz(irr * resp_ipol, wvl) + return np_trapezoid(irr * resp_ipol, wvl) # Divide by the equivalent band width: - return np.trapz(irr * resp_ipol, wvl) / np.trapz(resp_ipol, wvl) + return np_trapezoid(irr * resp_ipol, wvl) / np_trapezoid(resp_ipol, wvl) def interpolate(self, **options): """Interpolate Irradiance to a specified evenly spaced resolution/grid. diff --git a/pyspectral/utils.py b/pyspectral/utils.py index 38f54e2..32ec687 100644 --- a/pyspectral/utils.py +++ b/pyspectral/utils.py @@ -21,6 +21,7 @@ import logging import os +import sys import tarfile import warnings from functools import wraps @@ -29,6 +30,7 @@ import numpy as np import requests +from pyspectral._compat import np_trapezoid from pyspectral.bandnames import BANDNAMES from pyspectral.config import get_config @@ -224,7 +226,7 @@ def get_central_wave(wav, resp, weight=1.0): # if info['unit'].find('-1') > 0: # Wavenumber: # res *= - return np.trapz(resp * wav * weight, wav) / np.trapz(resp * weight, wav) + return np_trapezoid(resp * wav * weight, wav) / np_trapezoid(resp * weight, wav) def get_bandname_from_wavelength(sensor, wavelength, rsr, epsilon=0.1, multiple_bands=False): @@ -413,7 +415,8 @@ def _download_tarball_and_extract(tarball_url, local_pathname, extract_dir): handle.write(data) tar = tarfile.open(local_pathname) - tar.extractall(extract_dir) + tar_kwargs = {} if sys.version_info < (3, 12) else {"filter": "data"} + tar.extractall(extract_dir, **tar_kwargs) tar.close() os.remove(local_pathname) From d6b5c58d97cb0d14c4be6fc38cf11ab5fe0bb73c Mon Sep 17 00:00:00 2001 From: David Hoese Date: Fri, 19 Jul 2024 14:12:23 -0500 Subject: [PATCH 19/22] Add license header to _compat.py --- pyspectral/_compat.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pyspectral/_compat.py b/pyspectral/_compat.py index 21271da..db91199 100644 --- a/pyspectral/_compat.py +++ b/pyspectral/_compat.py @@ -1,3 +1,17 @@ +# Copyright (c) 2024 Pytroll developers +# +# This program 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. +# +# This program 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 this program. If not, see . """Various helpers for backwards and forwards compatibility.""" import numpy as np From 913d4febfeb86ed9c4f4a951e9bd45421ddcc463 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Wed, 14 Aug 2024 10:35:27 -0500 Subject: [PATCH 20/22] Replace deprecated numpy trapezoid/trapz usage with scipy trapezoid --- pyspectral/_compat.py | 19 ------------------- pyspectral/radiance_tb_conversion.py | 9 ++------- pyspectral/rsr_reader.py | 5 +++-- pyspectral/solar.py | 11 +++++------ pyspectral/utils.py | 4 ++-- setup.py | 2 +- 6 files changed, 13 insertions(+), 37 deletions(-) delete mode 100644 pyspectral/_compat.py diff --git a/pyspectral/_compat.py b/pyspectral/_compat.py deleted file mode 100644 index db91199..0000000 --- a/pyspectral/_compat.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2024 Pytroll developers -# -# This program 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. -# -# This program 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 this program. If not, see . -"""Various helpers for backwards and forwards compatibility.""" - -import numpy as np - -np_trapezoid = np.trapezoid if hasattr(np, "trapezoid") else np.trapz diff --git a/pyspectral/radiance_tb_conversion.py b/pyspectral/radiance_tb_conversion.py index 8b0b10c..549fa51 100644 --- a/pyspectral/radiance_tb_conversion.py +++ b/pyspectral/radiance_tb_conversion.py @@ -28,17 +28,12 @@ from numbers import Number import numpy as np +from scipy.integrate import trapezoid -from pyspectral._compat import np_trapezoid from pyspectral.blackbody import C_SPEED, H_PLANCK, K_BOLTZMANN, blackbody, blackbody_wn from pyspectral.rsr_reader import RelativeSpectralResponse from pyspectral.utils import BANDNAMES, WAVE_LENGTH, WAVE_NUMBER, convert2wavenumber, get_bandname_from_wavelength -try: - from scipy.integrate import trapezoid -except ImportError: - from scipy.integrate import trapz as trapezoid - LOG = logging.getLogger(__name__) BLACKBODY_FUNC = {WAVE_LENGTH: blackbody, @@ -160,7 +155,7 @@ def _get_rsr(self): self._wave_si_scale) self.response = self.rsr[self.bandname][self.detector]['response'] # Get the integral of the spectral response curve: - self.rsr_integral = np_trapezoid(self.response, self.wavelength_or_wavenumber) + self.rsr_integral = trapezoid(self.response, self.wavelength_or_wavenumber) def _getsatname(self): """Get the satellite name used in the rsr-reader, from the platform and number.""" diff --git a/pyspectral/rsr_reader.py b/pyspectral/rsr_reader.py index 50eea61..a107758 100644 --- a/pyspectral/rsr_reader.py +++ b/pyspectral/rsr_reader.py @@ -24,7 +24,8 @@ from glob import glob from os.path import expanduser -from pyspectral._compat import np_trapezoid +from scipy.integrate import trapezoid + from pyspectral.bandnames import BANDNAMES from pyspectral.config import get_config from pyspectral.utils import ( @@ -213,7 +214,7 @@ def integral(self, bandname): for det in self.rsr[bandname].keys(): wvl = self.rsr[bandname][det]['wavelength'] resp = self.rsr[bandname][det]['response'] - intg[det] = np_trapezoid(resp, wvl) + intg[det] = trapezoid(resp, wvl) return intg def convert(self): diff --git a/pyspectral/solar.py b/pyspectral/solar.py index e13e8f0..172bb32 100644 --- a/pyspectral/solar.py +++ b/pyspectral/solar.py @@ -29,8 +29,7 @@ from pathlib import Path import numpy as np - -from pyspectral._compat import np_trapezoid +from scipy.integrate import trapezoid LOG = logging.getLogger(__name__) @@ -123,9 +122,9 @@ def _load(self): def solar_constant(self): """Calculate the solar constant.""" if self.wavenumber is not None: - return np_trapezoid(self.irradiance, self.wavenumber) + return trapezoid(self.irradiance, self.wavenumber) if self.wavelength is not None: - return np_trapezoid(self.irradiance, self.wavelength) + return trapezoid(self.irradiance, self.wavelength) raise TypeError('Neither wavelengths nor wavenumbers available!') @@ -206,10 +205,10 @@ def _band_calculations(self, rsr, flux, scale, **options): # Calculate the solar-flux: (w/m2) if flux: - return np_trapezoid(irr * resp_ipol, wvl) + return trapezoid(irr * resp_ipol, wvl) # Divide by the equivalent band width: - return np_trapezoid(irr * resp_ipol, wvl) / np_trapezoid(resp_ipol, wvl) + return trapezoid(irr * resp_ipol, wvl) / trapezoid(resp_ipol, wvl) def interpolate(self, **options): """Interpolate Irradiance to a specified evenly spaced resolution/grid. diff --git a/pyspectral/utils.py b/pyspectral/utils.py index 32ec687..3ffe149 100644 --- a/pyspectral/utils.py +++ b/pyspectral/utils.py @@ -29,8 +29,8 @@ import numpy as np import requests +from scipy.integrate import trapezoid -from pyspectral._compat import np_trapezoid from pyspectral.bandnames import BANDNAMES from pyspectral.config import get_config @@ -226,7 +226,7 @@ def get_central_wave(wav, resp, weight=1.0): # if info['unit'].find('-1') > 0: # Wavenumber: # res *= - return np_trapezoid(resp * wav * weight, wav) / np_trapezoid(resp * weight, wav) + return trapezoid(resp * wav * weight, wav) / trapezoid(resp * weight, wav) def get_bandname_from_wavelength(sensor, wavelength, rsr, epsilon=0.1, multiple_bands=False): diff --git a/setup.py b/setup.py index f16e2e3..b851fa2 100644 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ with open('./README.md', 'r') as fd: long_description = fd.read() -requires = ['numpy', 'scipy', 'python-geotiepoints>=1.1.1', +requires = ['numpy', 'scipy>=1.6.0', 'python-geotiepoints>=1.1.1', 'h5py>=2.5', 'requests', 'pyyaml', 'platformdirs'] dask_extra = ['dask[array]'] From af71f1e70001067b5f94229c670c28d008d31ee9 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Wed, 14 Aug 2024 10:36:58 -0500 Subject: [PATCH 21/22] Remove trapz usage in rsr seviri script --- rsr_convert_scripts/seviri_rsr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rsr_convert_scripts/seviri_rsr.py b/rsr_convert_scripts/seviri_rsr.py index 951a804..cca4a2c 100644 --- a/rsr_convert_scripts/seviri_rsr.py +++ b/rsr_convert_scripts/seviri_rsr.py @@ -25,6 +25,7 @@ import numpy as np import pkg_resources +from scipy.integrate import trapezoid from xlrd import open_workbook from pyspectral.config import get_config @@ -210,7 +211,7 @@ def get_centrals(self): def get_central_wave(wavl, resp): """Calculate the central wavelength (or the central wavenumber if inputs are wave numbers).""" - return np.trapz(resp * wavl, wavl) / np.trapz(resp, wavl) + return trapezoid(resp * wavl, wavl) / trapezoid(resp, wavl) def generate_seviri_file(seviri, platform_name): From 604bd6d48254c628cb1f478967ea55656e466382 Mon Sep 17 00:00:00 2001 From: David Hoese Date: Wed, 14 Aug 2024 11:08:54 -0500 Subject: [PATCH 22/22] Update changelog for v0.13.4 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 200a0ab..6e457e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## Version v0.13.4 (2024/08/14) + +### Issues Closed + +* [Issue 229](https://github.com/pytroll/pyspectral/issues/229) - Deprecate old scipy and remove use of trapz (numpy and scipy) ([PR 233](https://github.com/pytroll/pyspectral/pull/233) by [@djhoese](https://github.com/djhoese)) + +In this release 1 issue was closed. + +### Pull Requests Merged + +#### Bugs fixed + +* [PR 233](https://github.com/pytroll/pyspectral/pull/233) - Replace deprecated numpy trapezoid/trapz usage with scipy trapezoid ([229](https://github.com/pytroll/pyspectral/issues/229)) +* [PR 232](https://github.com/pytroll/pyspectral/pull/232) - Cleanup unused dependencies and deprecated code + +In this release 2 pull requests were closed. + + ## Version v0.13.3 (2024/07/17) ### Pull Requests Merged