Skip to content

Commit c6f8a5f

Browse files
Merge pull request #350 from NNPDF/evolve-ekov015
Make `pineappl evolve` support EKO `v0.15`
2 parents a855d67 + 3d8d56a commit c6f8a5f

5 files changed

Lines changed: 101 additions & 2 deletions

File tree

.github/actions/cache-test-data/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ runs:
1010
uses: actions/cache@v4
1111
with:
1212
path: test-data
13-
key: test-data-v21
13+
key: test-data-v23
1414
- name: Download test data if cache miss
1515
if: steps.cache.outputs.cache-hit != 'true'
1616
run: |

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- added a new `V3` metadata reader to the `pineappl evolve` CLI for EKOs
13+
generated with `v0.15.0` or higher
14+
- C API: added new functions `pineappl_grid_evolve_info_shape`,
15+
`pineappl_grid_evolve_info`, and `pineappl_grid_evolve` to evolve grids
16+
- C API: added `pineappl_fktable_optimize` to optimize FK Table-like objects
17+
given an optimization assumption
18+
1019
## [1.0.0] - 10/06/2025
1120

1221
PineAPPL 1.0 is a major rewrite from the previous version, allowing grids to

maintainer/download-test-data.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ files=(
5050
'https://data.nnpdf.science/pineappl/test-data/STAR_WMWP_510GEV_WM-AL-POL_UnpolPDF.tar'
5151
'https://data.nnpdf.science/pineappl/test-data/ZEUS_2JET_319GEV_374PB-1_DIF_ETQ2_BIN6.pineappl.lz4'
5252
'https://data.nnpdf.science/pineappl/test-data/ZEUS_2JET_319GEV_374PB-1_DIF_ETQ2_BIN6.tar'
53+
'https://data.nnpdf.science/pineappl/test-data/LHCB_WP_8TEV.pineappl.lz4'
54+
'https://data.nnpdf.science/pineappl/test-data/LHCB_WP_8TEV.tar'
5355
'https://ploughshare.web.cern.ch/ploughshare/db/applfast/applfast-atlas-dijets-fnlo-arxiv-1312.3524/grids/applfast-atlas-dijets-fnlo-arxiv-1312.3524-xsec000.tab.gz'
5456
'https://ploughshare.web.cern.ch/ploughshare/db/applfast/applfast-h1-dijets-appl-arxiv-0010054/grids/applfast-h1-dijets-appl-arxiv-0010054-xsec000.appl'
5557
'https://ploughshare.web.cern.ch/ploughshare/db/applfast/applfast-h1-incjets-fnlo-arxiv-0706.3722/grids/applfast-h1-incjets-fnlo-arxiv-0706.3722-xsec000.tab.gz'

pineappl_cli/src/evolve.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ mod eko {
7070
V0(MetadataV0),
7171
V1(MetadataV1),
7272
V2(MetadataV2),
73+
V3(MetadataV3), // v0.15 - v????
7374
}
7475

7576
const BASES_V1_DEFAULT_PIDS: [i32; 14] = [22, -6, -5, -4, -3, -2, -1, 21, 1, 2, 3, 4, 5, 6];
@@ -86,6 +87,12 @@ mod eko {
8687
configs: OperatorConfigsV1,
8788
}
8889

90+
#[derive(Deserialize)]
91+
struct OperatorV2 {
92+
init: Vec<f64>,
93+
configs: OperatorConfigsV1,
94+
}
95+
8996
#[derive(Deserialize)]
9097
struct OperatorInfoV1 {
9198
scale: f64,
@@ -105,13 +112,18 @@ mod eko {
105112
bases: BasesV1,
106113
}
107114

115+
#[derive(Deserialize)]
116+
struct MetadataV3 {
117+
xgrid: Vec<f64>,
118+
}
119+
108120
pub enum EkoSlices {
109121
V0 {
110122
fac1: Vec<f64>,
111123
info: OperatorSliceInfo,
112124
operator: Array5<f64>,
113125
},
114-
// V1 is a special case of V2
126+
// V1 and V3 are special cases of V2
115127
V2 {
116128
fac1: HashMap<OsString, f64>,
117129
info: OperatorSliceInfo,
@@ -142,6 +154,7 @@ mod eko {
142154
Metadata::V0(v0) => Self::with_v0(v0, eko_path),
143155
Metadata::V1(v1) => Self::with_v1(v1, eko_path),
144156
Metadata::V2(v2) => Self::with_v2(v2, eko_path),
157+
Metadata::V3(v3) => Self::with_v3(v3, eko_path),
145158
}
146159
}
147160

@@ -325,6 +338,51 @@ mod eko {
325338
})
326339
}
327340

341+
fn with_v3(metadata: MetadataV3, eko_path: &Path) -> Result<Self> {
342+
let mut fac1 = HashMap::new();
343+
let mut operator: Option<OperatorV2> = None;
344+
345+
for entry in Archive::new(File::open(eko_path)?).entries_with_seek()? {
346+
let entry = entry?;
347+
let path = entry.path()?;
348+
349+
if path.starts_with("./operators")
350+
&& (path.extension().is_some_and(|ext| ext == "yaml"))
351+
{
352+
let Some(file_stem) = path.file_stem().map(ToOwned::to_owned) else {
353+
continue;
354+
};
355+
356+
let op_info: OperatorInfoV1 = serde_yaml::from_reader(entry)?;
357+
fac1.insert(file_stem, op_info.scale);
358+
} else if path.as_os_str() == "./operator.yaml" {
359+
operator = Some(serde_yaml::from_reader(entry)?);
360+
}
361+
}
362+
363+
let operator =
364+
operator.ok_or_else(|| anyhow!("no file 'operator.yaml' in EKO archive found"))?;
365+
366+
Ok(Self::V2 {
367+
fac1,
368+
info: OperatorSliceInfo {
369+
// NOTE: Since v0.15, EKOs are always in the flavour basis
370+
pid_basis: PidBasis::Pdg,
371+
fac0: operator.init[0] * operator.init[0],
372+
pids0: BASES_V1_DEFAULT_PIDS.to_vec(),
373+
x0: metadata.xgrid.clone(),
374+
fac1: 0.0,
375+
pids1: BASES_V1_DEFAULT_PIDS.to_vec(),
376+
x1: metadata.xgrid,
377+
conv_type: ConvType::new(
378+
operator.configs.polarized,
379+
operator.configs.time_like,
380+
),
381+
},
382+
archive: Archive::new(File::open(eko_path)?),
383+
})
384+
}
385+
328386
pub fn iter_mut(&mut self) -> EkoSlicesIter {
329387
match self {
330388
Self::V0 {

pineappl_cli/tests/evolve.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ const ZEUS_2JET_STR: &str = "b Grid FkTable rel. diff
190190
2 3.6247796e-3 3.6162230e-3 -2.3605729e-3
191191
";
192192

193+
const LHCB_WP_8TEV_STR: &str = "b Grid FkTable rel. diff
194+
-+-----------+-----------+-------------
195+
0 8.8660824e2 8.8745467e2 9.5468156e-4
196+
1 8.3324869e2 8.3388816e2 7.6744152e-4
197+
2 7.4379285e2 7.4420759e2 5.5761143e-4
198+
3 6.2114832e2 6.2135970e2 3.4030039e-4
199+
4 4.8212545e2 4.8218796e2 1.2966015e-4
200+
5 3.4357834e2 3.4355392e2 -7.1080989e-5
201+
6 1.7271792e2 1.7266488e2 -3.0707061e-4
202+
7 4.6738298e1 4.6715819e1 -4.8096830e-4
203+
";
204+
193205
#[test]
194206
fn help() {
195207
Command::cargo_bin("pineappl")
@@ -461,3 +473,21 @@ fn zeus_2jet() {
461473
.success()
462474
.stdout(ZEUS_2JET_STR);
463475
}
476+
477+
#[test]
478+
fn lhcb_wp_8tev() {
479+
let output = NamedTempFile::new("fktable8.lz4").unwrap();
480+
481+
Command::cargo_bin("pineappl")
482+
.unwrap()
483+
.args([
484+
"evolve",
485+
"../test-data/LHCB_WP_8TEV.pineappl.lz4",
486+
"../test-data/LHCB_WP_8TEV.tar",
487+
output.path().to_str().unwrap(),
488+
"NNPDF40_nnlo_as_01180",
489+
])
490+
.assert()
491+
.success()
492+
.stdout(LHCB_WP_8TEV_STR);
493+
}

0 commit comments

Comments
 (0)