Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 66 additions & 0 deletions maintainer/test-cli-export.sh
Original file line number Diff line number Diff line change
@@ -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"
"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"
"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"
"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
13 changes: 2 additions & 11 deletions pineappl/src/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
}
Expand Down
14 changes: 10 additions & 4 deletions pineappl/src/subgrid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
52 changes: 25 additions & 27 deletions pineappl_cli/src/export/applgrid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -156,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()
Expand Down Expand Up @@ -200,17 +213,17 @@ 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");

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
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
Expand Down Expand Up @@ -275,9 +288,7 @@ pub fn convert_into_applgrid(
})
.collect::<Result<_>>()?;

// 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()
Expand All @@ -298,26 +309,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
Expand Down Expand Up @@ -376,7 +374,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
Expand Down