From ecf5633fcff48d3e0c6160bbab63bd880ef061f9 Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Mon, 28 Sep 2026 12:37:46 +0200 Subject: [PATCH 1/4] Lift the scipy<1.18 cap; require camb>=2.0 camb 2.0 makes its BBN Y_He predictor return a scalar, so set_cosmology works under scipy 1.18.0 (whose RectBivariateSpline returned shape (1,) for scalar input). With that floor the scipy cap has no reason to exist. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LsAQRxNg6yDsUX4y2SWxTJ --- pyproject.toml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dabdae3..8a26ed8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,18 +15,13 @@ dependencies = [ "numpy>=1.26.4", "matplotlib>=3.8.4", "swig>=4.2.1", - # Cap scipy < 1.18: scipy 1.18 ported FITPACK from Fortran to C, changing - # RectBivariateSpline(scalar, scalar, grid=False) from a 0-d array to a - # shape-(1,) array. camb's BBN Y_He predictor then fails set_cosmology with - # "only 0-dimensional arrays can be converted to Python scalars", breaking - # every get_cosmo path (and pyccl's Boltzmann spline path likewise). camb - # 1.6.6 is unfixed; lift the cap when camb ships the scipy-1.18 fix. Mirrors - # the same cap in sp_validation. - "scipy>=1.13.0,<1.18", + "scipy>=1.13.0", "vos>=3.6.1", "keyring>=25.2.0", "pyccl>=3.0.2", - "camb>=1.5.9", + # camb 2.0 is the first release whose BBN Y_He predictor tolerates scipy + # 1.18.0's shape-(1,) spline output; older camb fails set_cosmology there. + "camb>=2.0", "healpy>=1.16.0", "healsparse>=1.8.0", ] From 8d210c037d3784fb476e1ab2a7530945cdd01555 Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Mon, 28 Sep 2026 12:51:40 +0200 Subject: [PATCH 2/4] cosmo: leave CAMB's min_l at its default in the camb C_ell backend get_theo_c_ell set pars.min_l = ell.min(), but CAMB's min_l is the scalar-C_ell floor and only takes 1 or 2. With camb 1.6.6 this underestimated C_ell at ell.min() by ~7.5%; with camb 2.0 any ell.min() > 10 raises 'You need to normalize realistically to use lensing' (the lensing sanity check reads C_phi at L=10). Add a test that C_ell at a given ell does not depend on the requested ell range. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LsAQRxNg6yDsUX4y2SWxTJ --- cs_util/cosmo.py | 5 +++-- cs_util/tests/test_cosmology.py | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cs_util/cosmo.py b/cs_util/cosmo.py index 501207a..f777541 100644 --- a/cs_util/cosmo.py +++ b/cs_util/cosmo.py @@ -716,8 +716,9 @@ def get_theo_c_ell( omch2_adj = camb_kwargs["omch2"] - pars.omeganu * (pars.H0 / 100) ** 2 pars.set_cosmology(omch2=omch2_adj) - # Set up lensing source window - pars.min_l = ell.min() + # Set up lensing source window. CAMB's min_l is the scalar-C_ell floor + # (1 or 2 only), so leave it at its default; ell below ell.min() are + # computed and discarded by the interpolation. pars.set_for_lmax(ell.max()) pars.SourceWindows = [ diff --git a/cs_util/tests/test_cosmology.py b/cs_util/tests/test_cosmology.py index 7116037..6f9447c 100644 --- a/cs_util/tests/test_cosmology.py +++ b/cs_util/tests/test_cosmology.py @@ -387,6 +387,13 @@ def test_camb_backend_tomo(self, fast_ell_array, fast_two_bins_data): except ImportError: pytest.skip("CAMB not available") + def test_camb_backend_ell_range_independent(self, fast_redshift_data): + """CAMB C_ell at a given ell does not depend on the requested ell range.""" + z, nz = fast_redshift_data + cl_wide = cosmology.get_theo_c_ell(np.array([10, 100, 1000]), z, nz, backend="camb") + cl_high = cosmology.get_theo_c_ell(np.array([100, 1000]), z, nz, backend="camb") + npt.assert_allclose(cl_high["W1xW1"], cl_wide["W1xW1"][1:], rtol=1e-6) + def test_invalid_backend(self, fast_ell_array, fast_redshift_data): """Test error with invalid backend.""" z, nz = fast_redshift_data From c3a940df1409f3778bf1a638b0e29229300be9ef Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Mon, 28 Sep 2026 15:31:50 +0200 Subject: [PATCH 3/4] Require pyccl>=3.3.5, the first release that runs boltzmann_camb on camb 2 Co-Authored-By: Claude Opus 5.5 --- pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8a26ed8..340437a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,9 @@ dependencies = [ "scipy>=1.13.0", "vos>=3.6.1", "keyring>=25.2.0", - "pyccl>=3.0.2", + # pyccl 3.3.5 is the first release that runs its boltzmann_camb path on camb 2 + # (LSSTDESC/CCL#1303); pyccl declares no camb dependency, so the floor lives here. + "pyccl>=3.3.5", # camb 2.0 is the first release whose BBN Y_He predictor tolerates scipy # 1.18.0's shape-(1,) spline output; older camb fails set_cosmology there. "camb>=2.0", From 3dd25748f58ecd18fe03ccb5f6c7ac7b6ee15806 Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Mon, 28 Sep 2026 15:43:45 +0200 Subject: [PATCH 4/4] Allow camb 1.x again; exclude only scipy 1.18.0 The breakage needed scipy 1.18.0 together with camb < 2.0; scipy 1.18.1 restores the 0-d spline result, so excluding the one scipy release is enough. Co-Authored-By: Claude Opus 5.5 --- pyproject.toml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 340437a..db7ac92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,15 +15,16 @@ dependencies = [ "numpy>=1.26.4", "matplotlib>=3.8.4", "swig>=4.2.1", - "scipy>=1.13.0", + # scipy 1.18.0 alone returns a shape-(1,) array from + # RectBivariateSpline(scalar, scalar, grid=False), which breaks the BBN Y_He + # predictor of camb < 2.0; scipy 1.18.1 restores the 0-d result. + "scipy>=1.13.0,!=1.18.0", "vos>=3.6.1", "keyring>=25.2.0", - # pyccl 3.3.5 is the first release that runs its boltzmann_camb path on camb 2 + # pyccl 3.3.5 is the first release whose boltzmann_camb path runs on camb 2 # (LSSTDESC/CCL#1303); pyccl declares no camb dependency, so the floor lives here. "pyccl>=3.3.5", - # camb 2.0 is the first release whose BBN Y_He predictor tolerates scipy - # 1.18.0's shape-(1,) spline output; older camb fails set_cosmology there. - "camb>=2.0", + "camb>=1.5.9", "healpy>=1.16.0", "healsparse>=1.8.0", ]