From 7dd0fb490da189544a2f94d04251eb2ef3fc4e1b Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Sun, 13 Jul 2025 12:01:05 +0200 Subject: [PATCH 1/7] Add test script for PineAPPL -> APPLgrid conversion --- maintainer/test-cli-export.sh | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100755 maintainer/test-cli-export.sh diff --git a/maintainer/test-cli-export.sh b/maintainer/test-cli-export.sh new file mode 100755 index 000000000..0880bae80 --- /dev/null +++ b/maintainer/test-cli-export.sh @@ -0,0 +1,66 @@ +#!/bin/bash -x + +set -euo pipefail + +grids=( + ## Ploughshare + + # Group: pinejet + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-wm-arxiv-1109.5141/pinejet-atlas-wm-arxiv-1109.5141.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-wm-arxiv-1603.09222/pinejet-atlas-wm-arxiv-1603.09222.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-wm-arxiv-1612.03016/pinejet-atlas-wm-arxiv-1612.03016.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-wp-arxiv-1109.5141/pinejet-atlas-wp-arxiv-1109.5141.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-wp-arxiv-1603.09222/pinejet-atlas-wp-arxiv-1603.09222.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-wp-arxiv-1612.03016/pinejet-atlas-wp-arxiv-1612.03016.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1109.5141/pinejet-atlas-z0-arxiv-1109.5141.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1305.4192/pinejet-atlas-z0-arxiv-1305.4192.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1404.1212/pinejet-atlas-z0-arxiv-1404.1212.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1603.09222/pinejet-atlas-z0-arxiv-1603.09222.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1606.01736/pinejet-atlas-z0-arxiv-1606.01736.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1612.03016/pinejet-atlas-z0-arxiv-1612.03016.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1710.05167/pinejet-atlas-z0-arxiv-1710.05167.tgz" + #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cdf-z0-arxiv-0908.3914/pinejet-cdf-z0-arxiv-0908.3914.tgz" # fails due to ppbar PDF mismatch + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wm-arxiv-1206.2598/pinejet-cms-wm-arxiv-1206.2598.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wm-arxiv-1312.6283/pinejet-cms-wm-arxiv-1312.6283.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wm-arxiv-1603.01803/pinejet-cms-wm-arxiv-1603.01803.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wp-arxiv-1206.2598/pinejet-cms-wp-arxiv-1206.2598.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wp-arxiv-1312.6283/pinejet-cms-wp-arxiv-1312.6283.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wp-arxiv-1603.01803/pinejet-cms-wp-arxiv-1603.01803.tgz" + #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-z0-arxiv-1310.7291/pinejet-cms-z0-arxiv-1310.7291.tgz" # fails due to static-scale optimization + #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-wm-arxiv-1309.2591/pinejet-d0-wm-arxiv-1309.2591.tgz" # fails du to ppbar PDF mismatch + #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-wp-arxiv-1309.2591/pinejet-d0-wp-arxiv-1309.2591.tgz" # fails du to ppbar PDF mismatch + #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-z0-arxiv-0702025/pinejet-d0-z0-arxiv-0702025.tgz" # fails du to ppbar PDF mismatch + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-wm-arxiv-1505.07024/pinejet-lhcb-wm-arxiv-1505.07024.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-wm-arxiv-1511.08039/pinejet-lhcb-wm-arxiv-1511.08039.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-wp-arxiv-1505.07024/pinejet-lhcb-wp-arxiv-1505.07024.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-wp-arxiv-1511.08039/pinejet-lhcb-wp-arxiv-1511.08039.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-z0-arxiv-1505.07024/pinejet-lhcb-z0-arxiv-1505.07024.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-z0-arxiv-1511.08039/pinejet-lhcb-z0-arxiv-1511.08039.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-z0-arxiv-1607.06495/pinejet-lhcb-z0-arxiv-1607.06495.tgz" +) + +tmp=$(mktemp -d) +cd "${tmp}" + +trap "cd && rm -rf ${tmp}" EXIT SIGKILL + +for grid in ${grids[@]}; do + archive=${grid##*/} + wget --no-verbose --no-clobber "${grid}" -O /tmp/"${archive}" || true + mkdir subdir + tar xzf /tmp/"${archive}" -C subdir + + for grid in $(find subdir \( -name '*.lz4' \)); do + if [[ $(basename $grid) =~ ^\..* ]]; then + continue + fi + + converted_grid="${grid}".appl + reimported_grid="${grid}".new.pineappl.lz4 + pineappl export --accuracy 1e-12 "${grid}" "${converted_grid}" NNPDF31_nnlo_as_0118_luxqed + pineappl import --accuracy 1e-12 "${converted_grid}" "${reimported_grid}" NNPDF31_nnlo_as_0118_luxqed + du -h "${converted_grid}" "${reimported_grid}" + done + + rm -r subdir +done From 2d7282039f7600782110f08f7a236e20d5c82938 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Sun, 13 Jul 2025 12:50:40 +0200 Subject: [PATCH 2/7] Add tentative fix for #357 --- pineappl/src/grid.rs | 13 ++----------- pineappl/src/subgrid.rs | 14 ++++++++++---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 48d2d84e4..82244a6c9 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -944,17 +944,8 @@ impl Grid { .multi_slice_mut((s![.., .., index], s![.., .., other_index])); for (lhs, rhs) in a.iter_mut().zip(b.iter_mut()) { - if !rhs.is_empty() { - if lhs.is_empty() { - // we can't merge into an EmptySubgridV1 - *lhs = mem::replace(rhs, EmptySubgridV1.into()); - // transpose `lhs` - todo!(); - } else { - lhs.merge(rhs, Some((a_subgrid, b_subgrid))); - *rhs = EmptySubgridV1.into(); - } - } + lhs.merge(rhs, Some((a_subgrid, b_subgrid))); + *rhs = EmptySubgridV1.into(); } } } diff --git a/pineappl/src/subgrid.rs b/pineappl/src/subgrid.rs index 799bb51ae..d575abaaf 100644 --- a/pineappl/src/subgrid.rs +++ b/pineappl/src/subgrid.rs @@ -418,15 +418,21 @@ impl SubgridEnum { if other.is_empty() { return; } + if let Self::EmptySubgridV1(_) = self { - if transpose.is_none() { + if transpose.is_some() { + // change the type of `self` to the type of `other` *self = other.clone(); + // TODO: emptying `self` could be done more efficiently, we're probably storing a + // lot of zeros here + self.scale(0.0); } else { - todo!(); + *self = other.clone(); + return; } - } else { - self.merge_impl(other, transpose); } + + self.merge_impl(other, transpose); } } From 16d4417548522cfd1278f938bbb0fb809e77e1a4 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Sun, 13 Jul 2025 13:57:37 +0200 Subject: [PATCH 3/7] Remove dead code --- pineappl_cli/src/export/applgrid.rs | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/pineappl_cli/src/export/applgrid.rs b/pineappl_cli/src/export/applgrid.rs index 109c9c098..75b72de5e 100644 --- a/pineappl_cli/src/export/applgrid.rs +++ b/pineappl_cli/src/export/applgrid.rs @@ -202,8 +202,8 @@ pub fn convert_into_applgrid( let mut applgrid = ffi::make_empty_grid(&limits, id, lo_alphas.into(), loops.into(), "f2", "h0"); - let has_pdf1 = !grid.convolutions().is_empty(); - let has_pdf2 = grid.convolutions().get(1).is_some(); + // APPLgrid has either two or one convolution(s) + let convolutions = grid.convolutions().len(); for (appl_order, order) in order_mask .iter() @@ -275,9 +275,7 @@ pub fn convert_into_applgrid( }) .collect::>()?; - // in the DIS case APPLgrid always uses the first x dimension - - let (x1_grid, x2_grid) = if has_pdf1 && has_pdf2 { + let (x1_grid, x2_grid) = if convolutions == 2 { ( grid.kinematics() .iter() @@ -298,26 +296,13 @@ pub fn convert_into_applgrid( // TODO: convert this into an error .unwrap(), ) - } else if has_pdf1 { - ( - grid.kinematics() - .iter() - .zip(subgrid.node_values()) - .find_map(|(kin, node_values)| { - matches!(kin, &Kinematics::X(idx) if idx == 0) - .then_some(node_values) - }) - // TODO: convert this into an error - .unwrap(), - Vec::new(), - ) } else { ( grid.kinematics() .iter() .zip(subgrid.node_values()) .find_map(|(kin, node_values)| { - matches!(kin, &Kinematics::X(idx) if idx == 1) + matches!(kin, &Kinematics::X(idx) if idx == 0) .then_some(node_values) }) // TODO: convert this into an error @@ -376,7 +361,7 @@ pub fn convert_into_applgrid( weightgrid.as_mut(), appl_q2_idx, appl_x1_idx[indices[1]], - if has_pdf1 && has_pdf2 { + if convolutions == 2 { appl_x2_idx[indices[2]] } else { 0 From 335e8c5e1ecab94943dc6c24cb389cb4ae2350a2 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Sun, 13 Jul 2025 15:01:50 +0200 Subject: [PATCH 4/7] Fix coupling order setting in APPLgrid exporter --- pineappl_cli/src/export/applgrid.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pineappl_cli/src/export/applgrid.rs b/pineappl_cli/src/export/applgrid.rs index 75b72de5e..7539db067 100644 --- a/pineappl_cli/src/export/applgrid.rs +++ b/pineappl_cli/src/export/applgrid.rs @@ -205,12 +205,12 @@ pub fn convert_into_applgrid( // APPLgrid has either two or one convolution(s) let convolutions = grid.convolutions().len(); - for (appl_order, order) in order_mask + for order in order_mask .iter() .enumerate() .filter_map(|(index, keep)| keep.then_some(index)) - .enumerate() { + let appl_order = grid.orders()[order].alphas - lo_alphas; let factor = TAU.powi(grid.orders()[order].alphas.into()); for (bin, subgrids) in grid From d337717ff9cb26b73ca55f16a3a5d25372c25f6a Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Sun, 20 Jul 2025 12:50:32 +0200 Subject: [PATCH 5/7] Fix export of proton-anti-proton grids to APPLgrid --- maintainer/test-cli-export.sh | 8 ++++---- pineappl_cli/src/export/applgrid.rs | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/maintainer/test-cli-export.sh b/maintainer/test-cli-export.sh index 0880bae80..c1afbb059 100755 --- a/maintainer/test-cli-export.sh +++ b/maintainer/test-cli-export.sh @@ -19,7 +19,7 @@ grids=( "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1606.01736/pinejet-atlas-z0-arxiv-1606.01736.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1612.03016/pinejet-atlas-z0-arxiv-1612.03016.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-atlas-z0-arxiv-1710.05167/pinejet-atlas-z0-arxiv-1710.05167.tgz" - #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cdf-z0-arxiv-0908.3914/pinejet-cdf-z0-arxiv-0908.3914.tgz" # fails due to ppbar PDF mismatch + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cdf-z0-arxiv-0908.3914/pinejet-cdf-z0-arxiv-0908.3914.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wm-arxiv-1206.2598/pinejet-cms-wm-arxiv-1206.2598.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wm-arxiv-1312.6283/pinejet-cms-wm-arxiv-1312.6283.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wm-arxiv-1603.01803/pinejet-cms-wm-arxiv-1603.01803.tgz" @@ -27,9 +27,9 @@ grids=( "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wp-arxiv-1312.6283/pinejet-cms-wp-arxiv-1312.6283.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-wp-arxiv-1603.01803/pinejet-cms-wp-arxiv-1603.01803.tgz" #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-cms-z0-arxiv-1310.7291/pinejet-cms-z0-arxiv-1310.7291.tgz" # fails due to static-scale optimization - #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-wm-arxiv-1309.2591/pinejet-d0-wm-arxiv-1309.2591.tgz" # fails du to ppbar PDF mismatch - #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-wp-arxiv-1309.2591/pinejet-d0-wp-arxiv-1309.2591.tgz" # fails du to ppbar PDF mismatch - #"https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-z0-arxiv-0702025/pinejet-d0-z0-arxiv-0702025.tgz" # fails du to ppbar PDF mismatch + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-wm-arxiv-1309.2591/pinejet-d0-wm-arxiv-1309.2591.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-wp-arxiv-1309.2591/pinejet-d0-wp-arxiv-1309.2591.tgz" + "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-d0-z0-arxiv-0702025/pinejet-d0-z0-arxiv-0702025.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-wm-arxiv-1505.07024/pinejet-lhcb-wm-arxiv-1505.07024.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-wm-arxiv-1511.08039/pinejet-lhcb-wm-arxiv-1511.08039.tgz" "https://ploughshare.web.cern.ch/ploughshare/db/pinejet/pinejet-lhcb-wp-arxiv-1505.07024/pinejet-lhcb-wp-arxiv-1505.07024.tgz" diff --git a/pineappl_cli/src/export/applgrid.rs b/pineappl_cli/src/export/applgrid.rs index 7539db067..e46913fb0 100644 --- a/pineappl_cli/src/export/applgrid.rs +++ b/pineappl_cli/src/export/applgrid.rs @@ -111,8 +111,19 @@ pub fn convert_into_applgrid( bail!("grid has non-consecutive bin limits, which APPLgrid does not support"); } - if grid.convolutions().len() > 2 { - bail!("APPLgrid does not support grids with more than two convolutions"); + match grid.convolutions() { + [_] => {} + [a, b] => { + if a != b { + if a.cc() == *b { + // use charge conjugate to map hadron-anti-hadron grids to use the same single + // convolution function + let index = if a.pid() < 0 { 0 } else { 1 }; + grid.charge_conjugate(index); + } + } + } + _ => bail!("APPLgrid does not support grids with more than two convolutions"), } // APPLgrid only understands PDG PIDs From 0c819cdd8a5e7952ad7064bdcc99c38454822448 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Sun, 20 Jul 2025 13:01:05 +0200 Subject: [PATCH 6/7] Update `CHANGELOG.md` --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4994e0660..92d282ac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- added a missing implementation for a branch in `Grid::merge` that was + triggered when exporting some PineAPPL grids generated from the 'pinejet' + group +- fixed wrong coupling orders when exporting to APPLgrid. This happened when + the PineAPPL grid had orders that had any other ordering than 'LO', 'NLO', + 'NNLO' +- fixed a bug that caused exported grids to compare unsuccessfully when the + convolution functions were proton-anti-proton; APPLgrid doesn't store the + types of convolution functions, so we simply convert the grid to use only + proton PDFs + ## [1.1.0] - 08/07/2025 ### Added From 6f1fed19655ae5bc4c7f1fc1bf91e9c1913495ad Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Tue, 12 Aug 2025 10:30:22 +0200 Subject: [PATCH 7/7] Make APPLgrid lumipdf name more unique --- pineappl_cli/src/export/applgrid.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pineappl_cli/src/export/applgrid.rs b/pineappl_cli/src/export/applgrid.rs index e46913fb0..a251a062b 100644 --- a/pineappl_cli/src/export/applgrid.rs +++ b/pineappl_cli/src/export/applgrid.rs @@ -167,9 +167,11 @@ pub fn convert_into_applgrid( .collect(); // `id` must end with '.config' for APPLgrid to know its type is `lumi_pdf` - let id = "PineAPPL-Lumi.config"; + let id = format!("{}.config", output.file_stem() + // UNWRAP: because we write to that file in the end, there always must be a file name + .unwrap().to_string_lossy()); // this object is managed by APPLgrid internally - ffi::make_lumi_pdf(id, &combinations).into_raw(); + ffi::make_lumi_pdf(&id, &combinations).into_raw(); let limits: Vec<_> = grid .bwfl() @@ -211,7 +213,7 @@ pub fn convert_into_applgrid( - lo_alphas; let mut applgrid = - ffi::make_empty_grid(&limits, id, lo_alphas.into(), loops.into(), "f2", "h0"); + ffi::make_empty_grid(&limits, &id, lo_alphas.into(), loops.into(), "f2", "h0"); // APPLgrid has either two or one convolution(s) let convolutions = grid.convolutions().len();