Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0a3d1b6
Add preliminary code for fastNLO exporter
cschwan Sep 26, 2024
0cf99c1
Add missing file
cschwan Sep 26, 2024
30cd1b7
Fix tests
cschwan Sep 26, 2024
7d2389f
Add code to initialize an new fastNLO table
cschwan Oct 14, 2024
745bb30
Fix binning
cschwan Jan 8, 2025
20f0b82
Merge branch 'master' into fastnlo-exporter
cschwan Nov 14, 2025
614faad
Fix compilation errors
cschwan Nov 14, 2025
17d6f75
Create container fastNLO version v2.6-3067
cschwan Nov 14, 2025
53bed5a
Resort packages in ascending order
cschwan Nov 14, 2025
04a1205
Generate autotools files for fastNLO in container
cschwan Nov 14, 2025
30af680
Install missing `autoreconf` into container
cschwan Nov 14, 2025
16d88d2
Change into right fastNLO directory
cschwan Nov 14, 2025
e920e88
Upgrade fastNLO to circumvent higher autotools requirements
cschwan Nov 14, 2025
e613e8b
Change into the right directory
cschwan Nov 14, 2025
a912cfc
Disable workflows in this branch
cschwan Nov 14, 2025
c98fbbd
Install `libtool` in container
cschwan Nov 14, 2025
4137fda
Add 'latest' tag in hope of fixing container upload
cschwan Nov 14, 2025
950976a
Revert "Disable workflows in this branch"
cschwan Nov 14, 2025
4a8e9d3
Revert "Resort packages in ascending order"
cschwan Apr 3, 2026
c5af6c6
Remove container tag
cschwan Apr 3, 2026
84aacfe
Merge branch 'master' into fastnlo-exporter
cschwan Apr 3, 2026
614eb81
Add fixes missing from merge
cschwan Apr 3, 2026
f3a57ac
Add clarifying comment
cschwan Apr 3, 2026
2d2c17f
Run `cargo fmt`
cschwan Apr 3, 2026
35f9634
Make error message more helpful
cschwan Apr 3, 2026
8f9e6a1
Fix bin-limits related bug
cschwan Apr 3, 2026
87b3ee3
Write out converted grid
cschwan Apr 3, 2026
8af86ee
Add code to convolve converted grid
cschwan Apr 3, 2026
1b646e5
Leave `wconst.Binning` empty to avoid failing check
cschwan Apr 6, 2026
c0994bb
Write out table in C++ function
cschwan Apr 6, 2026
5162aee
Set number of events to avoid division by zero
cschwan Apr 6, 2026
dfa5227
Avoid potentially unknow parton IDs
cschwan Apr 6, 2026
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
1 change: 1 addition & 0 deletions .github/workflows/container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
uses: redhat-actions/buildah-build@v2
with:
image: pineappl-ci
tags: latest
containerfiles: maintainer/Containerfile
context: maintainer/
oci: true
Expand Down
1 change: 1 addition & 0 deletions maintainer/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ENV APPL_IGRID_DIR="/usr/local/src/applgrid/src"

# the last version is the default Rust version used in the container
# as long as we're using `persist-doctests` in the `Rust` workflow we need nightly as default
# see also https://github.com/rust-lang/rust/issues/56925
ARG RUST_V="1.80.1 1.91.1 nightly-2026-03-10"

ENV CARGO_HOME="/usr/local/cargo"
Expand Down
2 changes: 2 additions & 0 deletions maintainer/build-container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
set -euo pipefail

pkgs=(
automake
build-essential
curl
gfortran
git
libssl-dev
libtool
openssl
pkg-config
)
Expand Down
13 changes: 10 additions & 3 deletions maintainer/install-cli-dependencies.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/bin/bash

APPLGRID_V=1.6.36
FASTNLO_V=2.5.0-2826
FASTNLO_V=2.6
FASTNLO_R=69d87cf4
LHAPDF_V=6.5.4
ZLIB_V=1.3.1

Expand All @@ -15,9 +16,12 @@ urls=(
"https://lhapdf.hepforge.org/downloads/?f=LHAPDF-${LHAPDF_V}.tar.gz"
"https://www.zlib.net/fossils/zlib-${ZLIB_V}.tar.gz"
"https://applgrid.hepforge.org/downloads/applgrid-${APPLGRID_V}.tgz"
"https://fastnlo.hepforge.org/code/v25/fastnlo_toolkit-${FASTNLO_V}.tar.gz"
# "https://fastnlo.hepforge.org/code/v25/fastnlo_toolkit-${FASTNLO_V}.tar.gz"
)

# download fastNLO from Git to support PineAPPL -> fastNLO export
git clone https://gitlab.etp.kit.edu/qcd-public/fastNLO.git

for url in "${urls[@]}"; do
curl -fsSL "${url}" | tar xzf -
done
Expand Down Expand Up @@ -83,7 +87,10 @@ cp src/*.h "${APPL_IGRID_DIR}"
cd ..

# install fastNLO
cd "fastnlo_toolkit-${FASTNLO_V}"
cd fastNLO
git checkout "${FASTNLO_R}"
cd "v${FASTNLO_V}/toolkit"
autoreconf -fi
if [[ ${static} == yes ]]; then
# compile static libraries with PIC to make statically linking PineAPPL's CLI work
./configure --prefix=/usr/local/ --disable-shared --with-pic=yes
Expand Down
2 changes: 1 addition & 1 deletion pineappl_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ rustc-args = [ "--cfg feature=\"docs-only\"" ]
[features]
applgrid = ["dep:cxx", "dep:pineappl_applgrid"]
evolve = ["dep:base64", "dep:either", "dep:tar", "dep:lz4_flex", "dep:ndarray-npy", "dep:serde", "dep:serde_yaml"]
fastnlo = ["dep:pineappl_fastnlo"]
fastnlo = ["dep:cxx", "dep:pineappl_fastnlo"]
fktable = ["dep:flate2", "dep:tar"]
static = ["lhapdf/static", "pineappl/static", "pineappl_applgrid?/static", "pineappl_fastnlo?/static"]
106 changes: 100 additions & 6 deletions pineappl_cli/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ use std::process::ExitCode;
#[cfg(feature = "applgrid")]
mod applgrid;

#[cfg(feature = "fastnlo")]
mod fastnlo;

#[cfg(feature = "applgrid")]
fn convert_into_applgrid(
output: &Path,
Expand Down Expand Up @@ -42,23 +45,113 @@ fn convert_into_applgrid(
))
}

#[cfg(feature = "fastnlo")]
fn convert_into_fastnlo(
output: &Path,
grid: &Grid,
fun_names: &ConvFuns,
scales: usize,
discard_non_matching_scales: bool,
) -> Result<(&'static str, Vec<f64>, usize, Vec<bool>)> {
use pineappl_fastnlo::ffi;

// TODO: other cases NYI
assert_eq!(scales, 1);

// TODO: convert this into an error?
assert_eq!(fun_names.lhapdf_names.len(), 1);

// this creates a file, but doesn't give us an object that we can convolve with a function
let order_mask = fastnlo::convert_into_fastnlo(grid, output, discard_non_matching_scales)?;

// so load this file, giving the right PDF set
let mut file = ffi::make_fastnlo_lhapdf_with_name_file_set(
output.to_str().unwrap(),
&fun_names.lhapdf_names[0],
// UNWRAP: this shouldn't be negative or overflow
fun_names.members[0].unwrap_or(0).try_into().unwrap(),
);

let mut reader = ffi::downcast_lhapdf_to_reader_mut(file.as_mut().unwrap());

// fastNLO does not support a fragmentation scale
let unpermuted_results: Vec<_> = helpers::SCALES_VECTOR_REN_FAC[0..scales]
.iter()
.map(|&(xir, xif, _)| {
if !reader.as_mut().SetScaleFactorsMuRMuF(xir, xif) {
return None;
}
reader.as_mut().CalcCrossSection();
Some(ffi::GetCrossSection(reader.as_mut(), false))
})
.take_while(Option::is_some)
.map(Option::unwrap)
.collect();

assert!(matches!(unpermuted_results.len(), 1 | 3 | 7 | 9));

let bins = unpermuted_results[0].len();

let results: Vec<_> = (0..bins)
.flat_map(|bin| unpermuted_results.iter().map(move |r| r[bin]))
.collect();

Ok(("fastNLO", results, scales, order_mask))
}

#[cfg(not(feature = "fastnlo"))]
fn convert_into_fastnlo(
_: &Path,
_: &Grid,
_: &ConvFuns,
_: usize,
_: bool,
) -> Result<(&'static str, Vec<f64>, usize, Vec<bool>)> {
Err(anyhow!(
"you need to install `pineappl` with feature `fastnlo`"
))
}

fn convert_into_grid(
output: &Path,
grid: &mut Grid,
conv_funs: &mut [Pdf],
fun_names: &ConvFuns,
scales: usize,
discard_non_matching_scales: bool,
) -> Result<(&'static str, Vec<f64>, usize, Vec<bool>)> {
if let Some(extension) = output.extension()
&& (extension == "appl" || extension == "root")
{
return convert_into_applgrid(output, grid, conv_funs, scales, discard_non_matching_scales);
if let Some(extension) = output.extension() {
if extension == "appl" || extension == "root" {
return convert_into_applgrid(
output,
grid,
conv_funs,
scales,
discard_non_matching_scales,
);
} else if extension == "tab"
|| (extension == "gz"
&& output
.with_extension("")
.extension()
.map_or(false, |ext| ext == "tab"))
{
return convert_into_fastnlo(
output,
grid,
fun_names,
scales,
discard_non_matching_scales,
);
}
}

Err(anyhow!("could not detect file format"))
Err(anyhow!(
"file extension must be one of: .appl, .root, .tab or .tab.gz"
))
}

/// Converts PineAPPL grids to APPLgrid files.
/// Converts PineAPPL grids to APPLgrid/fastNLO files.
#[derive(Parser)]
pub struct Opts {
/// Path to the input grid.
Expand Down Expand Up @@ -103,6 +196,7 @@ impl Subcommand for Opts {
&self.output,
&mut grid,
&mut conv_funs,
&self.conv_funs,
self.scales,
self.discard_non_matching_scales,
)?;
Expand Down
106 changes: 106 additions & 0 deletions pineappl_cli/src/export/fastnlo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use anyhow::{Result, bail};
use float_cmp::assert_approx_eq;
use pineappl::boc::Order;
use pineappl::grid::Grid;
use pineappl_fastnlo::ffi;
use std::path::Path;

pub fn convert_into_fastnlo(
grid: &Grid,
output: &Path,
_discard_non_matching_scales: bool,
) -> Result<Vec<bool>> {
let bwfl = grid.bwfl();
let dim = bwfl.dimensions();

if dim > 3 {
bail!(
"grid has {} dimensions, but fastNLO only supports up to three-dimensional distributions",
dim
);
}

let bins = bwfl.bins();
let left_bin_limits: Vec<Vec<_>> = bins
.iter()
.map(|bin| bin.limits().iter().map(|&(l, _)| l).collect())
.collect();
let right_bin_limits: Vec<Vec<_>> = bins
.iter()
.map(|bin| bin.limits().iter().map(|&(_, r)| r).collect())
.collect();
let normalizations = bwfl.normalizations();

let order_mask = Order::create_mask(grid.orders(), 3, 0, false);
let orders_with_mask: Vec<_> = grid
.orders()
.iter()
.cloned()
.zip(order_mask.iter().copied())
.collect();
let lo_alphas = orders_with_mask
.iter()
.filter_map(|&(Order { alphas, .. }, keep)| keep.then_some(alphas))
.min()
// UNWRAP: this will fail for `Grid` with no orders, but this shouldn't happen
.unwrap();
//let loops = orders_with_mask
// .iter()
// .filter_map(|&(Order { alphas, .. }, keep)| keep.then_some(alphas))
// .max()
// .unwrap()
// - lo_alphas;

let convolutions: Vec<i32> = grid.convolutions().iter().map(|conv| conv.pid()).collect();

// TODO: lift this restriction
assert_eq!(grid.convolutions().len(), 2);

let channels: Vec<Vec<_>> = grid
.channels()
.iter()
.map(|channel| {
channel
.entry()
.iter()
.map(|&(ref pids, factor)| {
assert_approx_eq!(f64, factor, 1.0, ulps = 4);
ffi::pair_int_int {
first: pids[0],
second: pids[1],
}
})
.collect()
})
.collect();

//for (fnlo_order, order) in order_mask
// .iter()
// .enumerate()
// .filter_map(|(index, keep)| keep.then_some(index))
// .enumerate()
//{}

ffi::make_fastnlo_create(
// UNWRAP: negative numbers and overflow should not happen
lo_alphas.try_into().unwrap(),
&left_bin_limits,
&right_bin_limits,
&normalizations,
// TODO: calculate channels for each order separately
// UNWRAP: negative numbers and overflow should not happen
channels.len().try_into().unwrap(),
// UNWRAP: negative numbers and overflow should not happen
channels.len().try_into().unwrap(),
// UNWRAP: negative numbers and overflow should not happen
channels.len().try_into().unwrap(),
&convolutions,
&channels,
&output
.to_str()
// TODO: decide what to do in case of an error
.unwrap(),
);

Ok(order_mask)
}
2 changes: 1 addition & 1 deletion pineappl_cli/tests/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use assert_cmd::Command;
#[cfg(feature = "applgrid")]
use assert_fs::NamedTempFile;

const HELP_STR: &str = "Converts PineAPPL grids to APPLgrid files
const HELP_STR: &str = "Converts PineAPPL grids to APPLgrid/fastNLO files

Usage: pineappl export [OPTIONS] <INPUT> <OUTPUT> <CONV_FUNS>

Expand Down
2 changes: 1 addition & 1 deletion pineappl_cli/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Commands:
convolve Convolutes a PineAPPL grid with a PDF set
diff Compares the numerical content of two grids with each other
evolve Evolve a grid with an evolution kernel operator to an FK table
export Converts PineAPPL grids to APPLgrid files
export Converts PineAPPL grids to APPLgrid/fastNLO files
help Display a manpage for selected subcommands
import Converts APPLgrid/fastNLO/FastKernel files to PineAPPL grids
merge Merges one or more PineAPPL grids together
Expand Down
Loading
Loading