diff --git a/.github/workflows/capi.yaml b/.github/workflows/capi.yaml index 90f3d0217..c89ca0e57 100644 --- a/.github/workflows/capi.yaml +++ b/.github/workflows/capi.yaml @@ -15,9 +15,11 @@ jobs: - uses: actions/checkout@v4 - name: Install PineAPPL's C API + env: + # `-C link-dead-code` is needed to prevent 'warning: XX functions have mismatched data' warnings + RUSTFLAGS: '-Cinstrument-coverage -Clink-dead-code' run: | - export RUSTFLAGS="-Cinstrument-coverage" - cargo cinstall --verbose --prefix=/usr/local/ --manifest-path pineappl_capi/Cargo.toml + cargo cinstall --verbose --prefix=/usr/local/ --libdir=lib --manifest-path pineappl_capi/Cargo.toml ldconfig - name: Test C++ example diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a28f8b3a4..e229d9559 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -7,11 +7,12 @@ on: jobs: test: - runs-on: ubuntu-latest + # `ubuntu-24.04` doesn't support Python 3.7 anymore + runs-on: ubuntu-22.04 strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -20,6 +21,9 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Test + env: + # `-C link-dead-code` is needed to prevent 'warning: XX functions have mismatched data' warnings + RUSTFLAGS: '-Cinstrument-coverage -Clink-dead-code' run: | cd pineappl_py python -m venv env diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5f36c1e44..edccf1a0a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -117,6 +117,7 @@ jobs: 3.9 3.11 3.12 + 3.13 3.10 - name: Install dependencies run: | @@ -379,6 +380,7 @@ jobs: 3.9 3.11 3.12 + 3.13 3.10 - name: Build wheels uses: PyO3/maturin-action@v1 @@ -429,6 +431,7 @@ jobs: 3.9 3.11 3.12 + 3.13 3.10 architecture: ${{ matrix.target }} - name: Build wheels diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f416ed0c3..c9297eb5c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -25,7 +25,7 @@ jobs: uses: actions/cache@v4 with: path: test-data - key: test-data-v12 + key: test-data-v15 - name: Download test data if: steps.cache-test-data.outputs.cache-hit != 'true' run: | @@ -38,6 +38,7 @@ jobs: curl -s -C - -O 'https://data.nnpdf.science/pineappl/test-data/E906nlo_bin_00.tar' curl -s -C - -O 'https://data.nnpdf.science/pineappl/test-data/FK_ATLASTTBARTOT13TEV.dat' curl -s -C - -O 'https://data.nnpdf.science/pineappl/test-data/FK_POSXDQ.dat' + curl -s -C - -O 'https://data.nnpdf.science/pineappl/test-data/LHC8-Mtt-HT4-173_3-bin1.tab.gz' curl -s -C - -O 'https://data.nnpdf.science/pineappl/test-data/LHCBWZMU7TEV_PI_part1.appl' curl -s -C - -O 'https://data.nnpdf.science/pineappl/test-data/LHCB_DY_8TEV.pineappl.lz4' curl -s -C - -O 'https://data.nnpdf.science/pineappl/test-data/LHCB_DY_8TEV.tar' @@ -66,7 +67,8 @@ jobs: - name: Run tests env: - RUSTFLAGS: '-Cinstrument-coverage' + # `-C link-dead-code` is needed to prevent 'warning: XX functions have mismatched data' warnings + RUSTFLAGS: '-Cinstrument-coverage -Clink-dead-code' run: | # we need stderr, but we can't run test twice because it'll regenerate/modify the binaries which interferes with `llvm-cov` cargo test --features=applgrid,evolve,fastnlo,fktable --no-fail-fast 2> >(tee stderr 1>&2) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fe08fc04..89c789d24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.8.7] - 22/01/2025 + +## Added + +- added support for Python 3.13 to the Python interface + +## [0.8.6] - 18/10/2024 + +### Fixed + +- fixed [Issue #318](https://github.com/NNPDF/pineappl/issues/318) that caused + fastNLO tables with `NPDFDim = 2` to be incorrectly imported + +## [0.8.5] - 07/10/2024 + +### Fixed + +- fixed a bug in `pineappl_applgrid` that lead to linking problems with ROOT + and `gfortran` + +## [0.8.4] - 04/10/2024 + +### Fixed + +- fixed a bug that lead to inconsistent convolution metadata + (https://github.com/NNPDF/pineappl/issues/316) + +## [0.8.3] - 30/08/2024 + +### Fixed + +- fixed a problem in the evolution when an EKO with 'similar' Q2 slices was + used to evolve; this caused the Q2 slices of the grids to be evolved several + times, leading to wrong results + ## [0.8.2] - 22/07/2024 ### Changed @@ -645,7 +680,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - first release -[Unreleased]: https://github.com/NNPDF/pineappl/compare/v0.8.2...HEAD +[Unreleased]: https://github.com/NNPDF/pineappl/compare/v0.8.7...HEAD +[0.8.7]: https://github.com/NNPDF/pineappl/compare/v0.8.6...v0.8.7 +[0.8.6]: https://github.com/NNPDF/pineappl/compare/v0.8.5...v0.8.6 +[0.8.5]: https://github.com/NNPDF/pineappl/compare/v0.8.4...v0.8.5 +[0.8.4]: https://github.com/NNPDF/pineappl/compare/v0.8.3...v0.8.4 +[0.8.3]: https://github.com/NNPDF/pineappl/compare/v0.8.2...v0.8.3 [0.8.2]: https://github.com/NNPDF/pineappl/compare/v0.8.1...v0.8.2 [0.8.1]: https://github.com/NNPDF/pineappl/compare/v0.8.0...v0.8.1 [0.8.0]: https://github.com/NNPDF/pineappl/compare/v0.7.4...v0.8.0 diff --git a/Cargo.lock b/Cargo.lock index 164f0ca68..aa090875f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,7 +242,7 @@ version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn", @@ -679,6 +679,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.4" @@ -902,16 +908,6 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.20" @@ -1083,9 +1079,9 @@ dependencies = [ [[package]] name = "numpy" -version = "0.21.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec170733ca37175f5d75a5bea5911d6ff45d2cd52849ce98b685394e4f2f37f4" +checksum = "edb929bc0da91a4d85ed6c0a84deaa53d411abfb387fc271124f91bf6b89f14e" dependencies = [ "libc", "ndarray", @@ -1117,29 +1113,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -1225,7 +1198,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pineappl" -version = "0.8.2" +version = "0.8.7" dependencies = [ "anyhow", "arrayvec", @@ -1250,7 +1223,7 @@ dependencies = [ [[package]] name = "pineappl_applgrid" -version = "0.8.2" +version = "0.8.7" dependencies = [ "cc", "cxx", @@ -1261,7 +1234,7 @@ dependencies = [ [[package]] name = "pineappl_capi" -version = "0.8.2" +version = "0.8.7" dependencies = [ "itertools", "pineappl", @@ -1269,7 +1242,7 @@ dependencies = [ [[package]] name = "pineappl_cli" -version = "0.8.2" +version = "0.8.7" dependencies = [ "anyhow", "assert_cmd", @@ -1300,7 +1273,7 @@ dependencies = [ [[package]] name = "pineappl_fastnlo" -version = "0.8.2" +version = "0.8.7" dependencies = [ "cxx", "cxx-build", @@ -1310,7 +1283,7 @@ dependencies = [ [[package]] name = "pineappl_py" -version = "0.8.2" +version = "0.8.7" dependencies = [ "itertools", "ndarray", @@ -1376,9 +1349,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -1398,15 +1371,15 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" +checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884" dependencies = [ "cfg-if", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -1416,9 +1389,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" +checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38" dependencies = [ "once_cell", "target-lexicon", @@ -1426,9 +1399,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636" dependencies = [ "libc", "pyo3-build-config", @@ -1436,9 +1409,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" +checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -1448,11 +1421,11 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "pyo3-build-config", "quote", @@ -1716,12 +1689,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "scratch" version = "1.0.7" @@ -1855,9 +1822,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -1883,9 +1850,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.13" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" @@ -2480,7 +2447,7 @@ dependencies = [ [[package]] name = "xtask" -version = "0.8.2" +version = "0.8.7" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 5e3d24451..129d2b65f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ keywords = ["high-energy-physics", "physics"] license = "GPL-3.0-or-later" repository = "https://github.com/NNPDF/pineappl" rust-version = "1.70.0" -version = "0.8.2" +version = "0.8.7" [workspace.lints.clippy] all = { level = "warn", priority = -1 } diff --git a/docs/installation.md b/docs/installation.md index d01aa21f3..d8cb00f0f 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -75,7 +75,7 @@ If you want to build the CAPI from its sources instead, you first need to 3. Now install `pineappl_capi`, PineAPPL's C API: cd pineappl_capi - cargo cinstall --release --prefix=${prefix} + cargo cinstall --release --prefix=${prefix} --libdir=lib cd .. where `${prefix}` points to the desired installation directory. diff --git a/maintainer/generate-coverage.sh b/maintainer/generate-coverage.sh index bba5931d8..ba4815bf6 100755 --- a/maintainer/generate-coverage.sh +++ b/maintainer/generate-coverage.sh @@ -11,6 +11,7 @@ wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl/test-data/E906nlo_bin_00.tar' wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl/test-data/FK_ATLASTTBARTOT13TEV.dat' wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl/test-data/FK_POSXDQ.dat' +wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl/test-data/LHC8-Mtt-HT4-173_3-bin1.tab.gz' wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl/test-data/LHCBWZMU7TEV_PI_part1.appl' wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl/test-data/LHCB_DY_8TEV.pineappl.lz4' wget --no-verbose --no-clobber -P test-data 'https://data.nnpdf.science/pineappl/test-data/LHCB_DY_8TEV.tar' diff --git a/maintainer/make-release.sh b/maintainer/make-release.sh index 74ce49421..074c9dfa0 100755 --- a/maintainer/make-release.sh +++ b/maintainer/make-release.sh @@ -19,9 +19,6 @@ features=( fktable ) -main=master -this_branch=$(git rev-parse --abbrev-ref HEAD) - cd .. if [[ $# != 1 ]]; then @@ -38,13 +35,6 @@ if [[ $(echo ${version} | grep -oP '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?: exit 1 fi -# in branches that are not master we only allow prereleases -if [[ ${this_branch} != ${main} ]] && [[ ${prerelease} == "" ]]; then - echo "Ordinary releases are only allowed in the '${main}' branch." - echo "If you really want to make a release from '${this_branch}', consider making a prerelease." - exit 1 -fi - for crate in ${crates[@]}; do if [[ -n $(git status ${crate} --porcelain) ]]; then echo "This repository isn't clean. Make sure to add or delete the corresponding files." @@ -72,12 +62,6 @@ for feature in ${features[@]}; do cargo test --release --features=${feature} done -echo ">>> Testing if 'pineappl' can be published ..." - -cd pineappl -cargo publish --dry-run -cd .. - echo ">>> Updating version strings ..." # we don't want to create a changelog entry for prereleases, which are solely @@ -107,6 +91,12 @@ echo ">>> Updating Cargo.lock ..." echo ${crates[@]} | xargs printf ' -p %s' | xargs cargo update git add Cargo.lock +echo ">>> Testing if 'pineappl' can be published ..." + +cd pineappl +cargo publish --dry-run +cd .. + echo ">>> Commiting and pushing changes ..." git commit -m "Release v${version}" diff --git a/pineappl/src/evolution.rs b/pineappl/src/evolution.rs index cefcc209e..83e57c3d2 100644 --- a/pineappl/src/evolution.rs +++ b/pineappl/src/evolution.rs @@ -16,7 +16,7 @@ use ndarray::{s, Array1, Array2, Array3, ArrayView1, ArrayView4, Axis}; use std::iter; /// Number of ULPS used to de-duplicate grid values in [`Grid::evolve_info`]. -pub(crate) const EVOLVE_INFO_TOL_ULPS: i64 = 64; +pub(crate) const EVOLVE_INFO_TOL_ULPS: i64 = 256; /// Number of ULPS used to search for grid values in this module. This value must be a large-enough /// multiple of [`EVOLVE_INFO_TOL_ULPS`], because otherwise similar values are not found in diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 86e744b97..c347891d4 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -12,7 +12,7 @@ use super::ntuple_subgrid::NtupleSubgridV1; use super::pids::{self, PidBasis}; use super::subgrid::{ExtraSubgridParams, Mu2, Subgrid, SubgridEnum, SubgridParams}; use bitflags::bitflags; -use float_cmp::approx_eq; +use float_cmp::{approx_eq, assert_approx_eq}; use git_version::git_version; use lz4_flex::frame::{FrameDecoder, FrameEncoder}; use ndarray::{s, Array3, ArrayView3, ArrayView5, ArrayViewMut3, Axis, CowArray, Dimension, Ix4}; @@ -856,6 +856,19 @@ impl Grid { self.set_key_value(&format!("convolution_type_{}", index + 1), &type_); self.set_key_value(&format!("convolution_particle_{}", index + 1), &particle); + + // update the remaining metadata + for (index, convolution) in self.convolutions().into_iter().enumerate() { + if self + .key_values() + // UNWRAP: we set some key-values before so there must be a storage + .unwrap_or_else(|| unreachable!()) + .get(&format!("initial_state_{}", index + 1)) + .is_some() + { + self.set_convolution(index, convolution); + } + } } fn increase_shape(&mut self, new_dim: &(usize, usize, usize)) { @@ -1411,11 +1424,40 @@ impl Grid { use super::evolution::EVOLVE_INFO_TOL_ULPS; let mut lhs: Option = None; - let mut fac1 = Vec::new(); + // Q2 slices we use + let mut used_op_fac1 = Vec::new(); + // Q2 slices we encounter, but possibly don't use + let mut op_fac1 = Vec::new(); + // Q2 slices needed by the grid + let grid_fac1: Vec<_> = self + .evolve_info(order_mask) + .fac1 + .into_iter() + .map(|fac| xi.1 * xi.1 * fac) + .collect(); for result in slices { let (info, operator) = result.map_err(|err| GridError::Other(err.into()))?; + op_fac1.push(info.fac1); + + // it's possible that due to small numerical differences we get two slices which are + // almost the same. We have to skip those in order not to evolve the 'same' slice twice + if used_op_fac1 + .iter() + .any(|&fac| approx_eq!(f64, fac, info.fac1, ulps = EVOLVE_INFO_TOL_ULPS)) + { + continue; + } + + // skip slices that the grid doesn't use + if !grid_fac1 + .iter() + .any(|&fac| approx_eq!(f64, fac, info.fac1, ulps = EVOLVE_INFO_TOL_ULPS)) + { + continue; + } + let op_info_dim = ( info.pids1.len(), info.x1.len(), @@ -1459,26 +1501,20 @@ impl Grid { lhs = Some(rhs); } - fac1.push(info.fac1); + used_op_fac1.push(info.fac1); } // UNWRAP: if we can't compare two numbers there's a bug - fac1.sort_by(|a, b| a.partial_cmp(b).unwrap_or_else(|| unreachable!())); + op_fac1.sort_by(|a, b| a.partial_cmp(b).unwrap_or_else(|| unreachable!())); // make sure we've evolved all slices - if let Some(muf2) = self - .evolve_info(order_mask) - .fac1 - .into_iter() - .map(|mu2| xi.1 * xi.1 * mu2) - .find(|&grid_mu2| { - !fac1 - .iter() - .any(|&eko_mu2| approx_eq!(f64, grid_mu2, eko_mu2, ulps = EVOLVE_INFO_TOL_ULPS)) - }) - { + if let Some(muf2) = grid_fac1.into_iter().find(|&grid_mu2| { + !used_op_fac1 + .iter() + .any(|&eko_mu2| approx_eq!(f64, grid_mu2, eko_mu2, ulps = EVOLVE_INFO_TOL_ULPS)) + }) { return Err(GridError::EvolutionFailure(format!( - "no operator for muf2 = {muf2} found in {fac1:?}" + "no operator for muf2 = {muf2} found in {op_fac1:?}" ))); } @@ -1512,12 +1548,49 @@ impl Grid { use itertools::izip; let mut lhs: Option = None; - let mut fac1 = Vec::new(); + // Q2 slices we use + let mut used_op_fac1 = Vec::new(); + // Q2 slices we encounter, but possibly don't use + let mut op_fac1 = Vec::new(); + // Q2 slices needed by the grid + let grid_fac1: Vec<_> = self + .evolve_info(order_mask) + .fac1 + .into_iter() + .map(|fac| xi.1 * xi.1 * fac) + .collect(); // TODO: simplify the ugly repetition below by offloading some ops into fn for (result_a, result_b) in izip!(slices_a, slices_b) { // Operate on `slices_a` let (info_a, operator_a) = result_a.map_err(|err| GridError::Other(err.into()))?; + // Operate on `slices_b` + let (info_b, operator_b) = result_b.map_err(|err| GridError::Other(err.into()))?; + + // TODO: what if the scales of the EKOs don't agree? Is there an ordering problem? + assert_approx_eq!(f64, info_a.fac1, info_b.fac1, ulps = EVOLVE_INFO_TOL_ULPS); + + // also the PID bases must be the same + assert_eq!(info_a.pid_basis, info_b.pid_basis); + + op_fac1.push(info_a.fac1); + + // it's possible that due to small numerical differences we get two slices which are + // almost the same. We have to skip those in order not to evolve the 'same' slice twice + if used_op_fac1 + .iter() + .any(|&fac| approx_eq!(f64, fac, info_a.fac1, ulps = EVOLVE_INFO_TOL_ULPS)) + { + continue; + } + + // skip slices that the grid doesn't use + if !grid_fac1 + .iter() + .any(|&fac| approx_eq!(f64, fac, info_a.fac1, ulps = EVOLVE_INFO_TOL_ULPS)) + { + continue; + } let op_info_dim_a = ( info_a.pids1.len(), @@ -1534,9 +1607,6 @@ impl Grid { ))); } - // Operate on `slices_b` - let (info_b, operator_b) = result_b.map_err(|err| GridError::Other(err.into()))?; - let op_info_dim_b = ( info_b.pids1.len(), info_b.x1.len(), @@ -1586,8 +1656,6 @@ impl Grid { more_members: self.more_members.clone(), }; - assert_eq!(infos[0].pid_basis, infos[1].pid_basis); - // TODO: use a new constructor to set this information rhs.set_pid_basis(infos[0].pid_basis); @@ -1597,27 +1665,20 @@ impl Grid { lhs = Some(rhs); } - // NOTE: The following should be shared by the 2 EKOs(?) - fac1.push(infos[0].fac1); + used_op_fac1.push(infos[0].fac1); } // UNWRAP: if we can't compare two numbers there's a bug - fac1.sort_by(|a, b| a.partial_cmp(b).unwrap_or_else(|| unreachable!())); + op_fac1.sort_by(|a, b| a.partial_cmp(b).unwrap_or_else(|| unreachable!())); // make sure we've evolved all slices - if let Some(muf2) = self - .evolve_info(order_mask) - .fac1 - .into_iter() - .map(|mu2| xi.1 * xi.1 * mu2) - .find(|&grid_mu2| { - !fac1 - .iter() - .any(|&eko_mu2| approx_eq!(f64, grid_mu2, eko_mu2, ulps = EVOLVE_INFO_TOL_ULPS)) - }) - { + if let Some(muf2) = grid_fac1.into_iter().find(|&grid_mu2| { + !used_op_fac1 + .iter() + .any(|&eko_mu2| approx_eq!(f64, grid_mu2, eko_mu2, ulps = EVOLVE_INFO_TOL_ULPS)) + }) { return Err(GridError::EvolutionFailure(format!( - "no operator for muf2 = {muf2} found in {fac1:?}" + "no operator for muf2 = {muf2} found in {op_fac1:?}" ))); } @@ -1816,7 +1877,6 @@ impl Grid { mod tests { use super::*; use crate::channel; - use float_cmp::assert_approx_eq; use std::fs::File; #[test] diff --git a/pineappl_applgrid/build.rs b/pineappl_applgrid/build.rs index 7719d3e7c..699122a24 100644 --- a/pineappl_applgrid/build.rs +++ b/pineappl_applgrid/build.rs @@ -115,6 +115,14 @@ fn main() { "" }; + // `--ldflags` contains linker paths not contained in `--libdir` + for lib_path in libs + .split_whitespace() + .filter_map(|token| token.strip_prefix("-L")) + { + println!("cargo:rustc-link-search={lib_path}"); + } + for lib in libs .split_whitespace() .filter_map(|token| token.strip_prefix("-l")) diff --git a/pineappl_capi/Cargo.toml b/pineappl_capi/Cargo.toml index eeb0d0446..37aca902c 100644 --- a/pineappl_capi/Cargo.toml +++ b/pineappl_capi/Cargo.toml @@ -16,7 +16,7 @@ version.workspace = true workspace = true [dependencies] -pineappl = { path = "../pineappl", version = "=0.8.2" } +pineappl = { path = "../pineappl", version = "=0.8.7" } itertools = "0.10.1" [features] diff --git a/pineappl_cli/Cargo.toml b/pineappl_cli/Cargo.toml index bc0bdadb2..1ee941051 100644 --- a/pineappl_cli/Cargo.toml +++ b/pineappl_cli/Cargo.toml @@ -30,9 +30,9 @@ lhapdf = { package = "managed-lhapdf", version = "0.3.2" } lz4_flex = { optional = true, version = "0.9.2" } ndarray = "0.15.4" ndarray-npy = { optional = true, version = "0.8.1" } -pineappl = { path = "../pineappl", version = "=0.8.2" } -pineappl_applgrid = { optional = true, path = "../pineappl_applgrid", version = "=0.8.2" } -pineappl_fastnlo = { optional = true, path = "../pineappl_fastnlo", version = "=0.8.2" } +pineappl = { path = "../pineappl", version = "=0.8.7" } +pineappl_applgrid = { optional = true, path = "../pineappl_applgrid", version = "=0.8.7" } +pineappl_fastnlo = { optional = true, path = "../pineappl_fastnlo", version = "=0.8.7" } prettytable-rs = { default-features = false, features = ["win_crlf"], version = "0.10.0" } rayon = "1.5.1" serde = { features = ["derive"], optional = true, version = "1.0.130" } diff --git a/pineappl_cli/src/import/fastnlo.rs b/pineappl_cli/src/import/fastnlo.rs index 4e79d3f33..8e4225938 100644 --- a/pineappl_cli/src/import/fastnlo.rs +++ b/pineappl_cli/src/import/fastnlo.rs @@ -13,6 +13,7 @@ use pineappl_fastnlo::ffi::{ fastNLOPDFLinearCombinations, EScaleFunctionalForm, }; use std::f64::consts::TAU; +use std::mem; fn pid_to_pdg_id(pid: i32) -> i32 { match pid { @@ -130,6 +131,8 @@ fn convert_coeff_add_fix( let total_scalenodes: usize = table.GetTotalScalenodes().try_into().unwrap(); + let npdfdim = table.GetNPDFDim(); + for obs in 0..table_as_add_base.GetNObsBin() { let x1_values = ffi::GetXNodes1(table_as_add_base, obs); @@ -178,13 +181,21 @@ fn convert_coeff_add_fix( table.GetSigmaTilde(obs, j, mu2_slice.try_into().unwrap(), ix, subproc); if value != 0.0 { + if npdfdim == 2 { + mem::swap(&mut ix1, &mut ix2); + } + array[[mu2_slice, ix2, ix1]] = value / factor * x1_values[ix1] * x2_values[ix2]; + + if npdfdim == 2 { + mem::swap(&mut ix1, &mut ix2); + } } ix1 += 1; - match table.GetNPDFDim() { + match npdfdim { 2 => { if ix1 == x1_values.len() { ix1 = 0; diff --git a/pineappl_cli/tests/import.rs b/pineappl_cli/tests/import.rs index c66f66c2d..630d3a20a 100644 --- a/pineappl_cli/tests/import.rs +++ b/pineappl_cli/tests/import.rs @@ -306,6 +306,16 @@ const IMPORT_DOUBLE_HADRONIC_FASTNLO_STR: &str = 20 2.0326950e-2 2.0326950e-2 6.6613381e-15 1.3211654e-14 "; +#[cfg(feature = "fastnlo")] +const IMPORT_NPDFDIM_2_TABLE_STR: &str = "0 1.0824021e0 1.0824021e0 1.4654944e-14 +1 1.0680553e0 1.0680553e0 -1.4432899e-15 +2 6.4959982e-1 6.4959982e-1 4.4408921e-15 +3 3.3033872e-1 3.3033872e-1 2.0872193e-14 +4 1.3360159e-1 1.3360159e-1 -2.3092639e-14 +5 3.2728146e-2 3.2728146e-2 -5.7731597e-15 +6 3.8508907e-3 3.8508907e-3 2.2870594e-14 +"; + #[test] fn help() { Command::cargo_bin("pineappl") @@ -1268,3 +1278,21 @@ fn import_double_hadronic_fastnlo() { IMPORT_DOUBLE_HADRONIC_FASTNLO_STR, )); } + +#[test] +#[cfg(feature = "fastnlo")] +fn import_npdfdim_2_table() { + let output = NamedTempFile::new("converted10.pineappl.lz4").unwrap(); + + Command::cargo_bin("pineappl") + .unwrap() + .args([ + "import", + "../test-data/LHC8-Mtt-HT4-173_3-bin1.tab.gz", + output.path().to_str().unwrap(), + "NNPDF31_nlo_as_0118_luxqed", + ]) + .assert() + .success() + .stdout(predicates::str::ends_with(IMPORT_NPDFDIM_2_TABLE_STR)); +} diff --git a/pineappl_py/Cargo.toml b/pineappl_py/Cargo.toml index 526e3dff4..a7e4c9e65 100644 --- a/pineappl_py/Cargo.toml +++ b/pineappl_py/Cargo.toml @@ -29,6 +29,6 @@ crate-type = ["cdylib"] [dependencies] itertools = "0.10.1" ndarray = "0.15.4" -numpy = "0.21.0" -pineappl = { path = "../pineappl", version = "=0.8.2" } -pyo3 = { features = ["extension-module"], version = "0.21.2" } +numpy = "0.22.0" +pineappl = { path = "../pineappl", version = "=0.8.7" } +pyo3 = { features = ["extension-module", "gil-refs"], version = "0.22.0" } diff --git a/pineappl_py/pyproject.toml b/pineappl_py/pyproject.toml index cb0886107..7933a800e 100644 --- a/pineappl_py/pyproject.toml +++ b/pineappl_py/pyproject.toml @@ -20,8 +20,8 @@ classifiers = [ "Programming Language :: Rust", "Topic :: Scientific/Engineering :: Physics", ] - -dependencies = ["numpy>=1.16.0,<2.0.0"] +dependencies = ["numpy>=1.16.0"] +dynamic = ["version"] [project.optional-dependencies] cli = ["pineappl-cli"] diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index ec43717e1..55a6b6809 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -273,7 +273,7 @@ impl PyFkTable { bin_indices: Option>, lumi_mask: Option>, py: Python<'py>, - ) -> &'py PyArray1 { + ) -> Bound<'py, PyArray1> { let mut xfx1 = |id, x, q2| f64::extract(xfx1.call1((id, x, q2)).unwrap()).unwrap(); let mut xfx2 = |id, x, q2| f64::extract(xfx2.call1((id, x, q2)).unwrap()).unwrap(); let mut alphas = |_| 1.0; @@ -285,7 +285,7 @@ impl PyFkTable { &bin_indices.map_or(vec![], |b| b.to_vec().unwrap()), &lumi_mask.map_or(vec![], |l| l.to_vec().unwrap()), ) - .into_pyarray(py) + .into_pyarray_bound(py) } /// Optimize FK table storage diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 908d0fc67..c3402b36b 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -21,4 +21,4 @@ clap_mangen = "0.2.18" enum_dispatch = "0.3.7" #git2 = "0.17.2" #semver = "1.0.17" -pineappl_cli = { path = "../pineappl_cli", version = "=0.8.2" } +pineappl_cli = { path = "../pineappl_cli", version = "=0.8.7" }