From 84dc918e07510bdaf8dff9148cf8be82cdf2b31e Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Mon, 10 Feb 2025 11:38:25 +0100 Subject: [PATCH] Add `--fk-table-{fac0,frg0}` switches to `pineappl read` --- CHANGELOG.md | 3 +++ pineappl/src/fk_table.rs | 37 +++++++++++++++++++----------- pineappl_cli/src/read.rs | 31 ++++++++++++++++++++++--- pineappl_cli/tests/import.rs | 20 +++++++++++++--- pineappl_cli/tests/read.rs | 14 ++++++----- pineappl_py/src/fk_table.rs | 19 +++++++++++---- pineappl_py/tests/test_fk_table.py | 3 ++- 7 files changed, 96 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e162574c3..a8c49e158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ the old file format can still be read with this new version. - the CLI now allows the user to mark convolution functions as polarized by adding `+p` to its LHAPDF name, as a fragmentation function by adding `+f` and both by adding `+pf` or `+fp` +- added switches `--fk-table-fac0` and `--fk-table-frg0` to `pineappl read` to + read out the squared factorization and fragmentation scales of FK-tables ### Changed @@ -51,6 +53,7 @@ the old file format can still be read with this new version. `--set-bins`, `--remap-norm-ignore` to `--div-bin-norm-dims` and `--remap-norm` to `--mul-bin-norm`. These names should reflect the corresponding operations +- renamed the switch `--fktable` to `--fk-table` of `pineappl read` ### Removed diff --git a/pineappl/src/fk_table.rs b/pineappl/src/fk_table.rs index fbc16cb3d..2e1e81b28 100644 --- a/pineappl/src/fk_table.rs +++ b/pineappl/src/fk_table.rs @@ -8,6 +8,7 @@ use super::grid::Grid; use super::pids::OptRules; use super::subgrid::{self, Subgrid}; use ndarray::{s, ArrayD}; +use std::collections::BTreeMap; use std::fmt::{self, Display, Formatter}; use std::iter; use std::str::FromStr; @@ -189,24 +190,32 @@ impl FkTable { /// Returns the single `muf2` scale of this `FkTable`. #[must_use] - pub fn muf2(&self) -> f64 { - let [muf2] = self.grid.evolve_info(&[true]).fac1[..] - .try_into() - // UNWRAP: every `FkTable` has only a single factorization scale - .unwrap_or_else(|_| unreachable!()); - - muf2 + pub fn fac0(&self) -> Option { + let fac1 = self.grid.evolve_info(&[true]).fac1; + + if let [fac0] = fac1[..] { + Some(fac0) + } else if fac1.is_empty() { + None + } else { + // UNWRAP: every `FkTable` has either a single factorization scale or none + unreachable!() + } } /// Return the initial fragmentation scale. #[must_use] - pub fn frg0(&self) -> f64 { - let [frg0] = self.grid.evolve_info(&[true]).frg1[..] - .try_into() - // UNWRAP: every `FkTable` has only a single fragmentation scale - .unwrap_or_else(|_| unreachable!()); - - frg0 + pub fn frg0(&self) -> Option { + let frg1 = self.grid.evolve_info(&[true]).frg1; + + if let [frg0] = frg1[..] { + Some(frg0) + } else if frg1.is_empty() { + None + } else { + // UNWRAP: every `FkTable` has either a single fragmentation scale or none + unreachable!() + } } /// Set a metadata key-value pair for this FK table. diff --git a/pineappl_cli/src/read.rs b/pineappl_cli/src/read.rs index c72f34025..d888f0a77 100644 --- a/pineappl_cli/src/read.rs +++ b/pineappl_cli/src/read.rs @@ -29,8 +29,13 @@ struct Group { channels: bool, /// Check if input is an FK table. #[arg(long)] - fktable: bool, - + fk_table: bool, + /// Return the (squared) factorization scale of the FK-table. + #[arg(long)] + fk_table_fac0: bool, + /// Return the (squared) fragmentation scale of the FK-table. + #[arg(long)] + fk_table_frg0: bool, /// For each order print a list of the largest EW order. #[arg(long)] ew: bool, @@ -88,13 +93,33 @@ impl Subcommand for Opts { row.add_cell(cell!(r->bin.normalization().to_string())); } - } else if self.group.fktable { + } else if self.group.fk_table { if let Err(err) = FkTable::try_from(grid) { println!("no\n{err}"); return Ok(ExitCode::FAILURE); } println!("yes"); + return Ok(ExitCode::SUCCESS); + } else if self.group.fk_table_fac0 { + let fk_table = FkTable::try_from(grid)?; + + if let Some(fac0) = fk_table.fac0() { + println!("{fac0}"); + } else { + println!("None"); + } + + return Ok(ExitCode::SUCCESS); + } else if self.group.fk_table_frg0 { + let fk_table = FkTable::try_from(grid)?; + + if let Some(frg0) = fk_table.frg0() { + println!("{frg0}"); + } else { + println!("None"); + } + return Ok(ExitCode::SUCCESS); } else if self.group.channels { let mut titles = row![c => "c"]; diff --git a/pineappl_cli/tests/import.rs b/pineappl_cli/tests/import.rs index 00fcf3406..159e9f3c0 100644 --- a/pineappl_cli/tests/import.rs +++ b/pineappl_cli/tests/import.rs @@ -705,18 +705,32 @@ fn import_dis_fktable() { Command::cargo_bin("pineappl") .unwrap() - .args(["read", "--fktable", output.path().to_str().unwrap()]) + .args(["read", "--fk-table", output.path().to_str().unwrap()]) .assert() .success() .stdout("yes\n"); + Command::cargo_bin("pineappl") + .unwrap() + .args(["read", "--fk-table-fac0", output.path().to_str().unwrap()]) + .assert() + .success() + .stdout("2.7224999999999997\n"); + + Command::cargo_bin("pineappl") + .unwrap() + .args(["read", "--fk-table-frg0", output.path().to_str().unwrap()]) + .assert() + .success() + .stdout("None\n"); + let fk_table = FkTable::try_from(Grid::read(File::open(output.path()).unwrap()).unwrap()).unwrap(); // TODO: this should ideally be a unit test, but we need an FK table that we don't convert assert_eq!(fk_table.grid().kinematics().len(), 2); - assert_approx_eq!(f64, fk_table.muf2(), 1.65 * 1.65, ulps = 2); + assert_approx_eq!(f64, fk_table.fac0().unwrap(), 1.65 * 1.65, ulps = 2); assert_eq!( fk_table.x_grid(), [ @@ -985,7 +999,7 @@ fn import_hadronic_fktable() { [115, 115] ] ); - assert_approx_eq!(f64, fk_table.muf2(), 1.65 * 1.65, ulps = 2); + assert_approx_eq!(f64, fk_table.fac0().unwrap(), 1.65 * 1.65, ulps = 2); assert_eq!( fk_table.x_grid(), [ diff --git a/pineappl_cli/tests/read.rs b/pineappl_cli/tests/read.rs index 2e9120a3c..a479413bf 100644 --- a/pineappl_cli/tests/read.rs +++ b/pineappl_cli/tests/read.rs @@ -4,7 +4,7 @@ use assert_cmd::Command; const HELP_STR: &str = "Read out information of a grid -Usage: pineappl read <--orders|--orders-spaces|--orders-long|--bins|--channels|--fktable|--ew|--get |--keys|--qcd|--show> +Usage: pineappl read <--orders|--orders-spaces|--orders-long|--bins|--channels|--fk-table|--fk-table-fac0|--fk-table-frg0|--ew|--get |--keys|--qcd|--show> Arguments: Path to the input grid @@ -15,7 +15,9 @@ Options: --orders-long Show the orders of a grid, including zero powers -b, --bins Show the bins of a grid --channels Show the channel definition of a grid - --fktable Check if input is an FK table + --fk-table Check if input is an FK table + --fk-table-fac0 Return the (squared) factorization scale of the FK-table + --fk-table-frg0 Return the (squared) fragmentation scale of the FK-table --ew For each order print a list of the largest EW order --get Gets an internal key-value pair --keys Show all keys stored in the grid @@ -78,7 +80,7 @@ multiple orders detected const WRONG_ORDERS_STR: &str = "error: the argument '--orders' cannot be used with '--orders-long' -Usage: pineappl read <--orders|--orders-spaces|--orders-long|--bins|--channels|--fktable|--ew|--get |--keys|--qcd|--show> +Usage: pineappl read <--orders|--orders-spaces|--orders-long|--bins|--channels|--fk-table|--fk-table-fac0|--fk-table-frg0|--ew|--get |--keys|--qcd|--show> For more information, try '--help'. "; @@ -545,7 +547,7 @@ y_unit: pb const WRONG_ARGUMENTS_STR: &str = "error: the argument '--ew' cannot be used with '--qcd' -Usage: pineappl read <--orders|--orders-spaces|--orders-long|--bins|--channels|--fktable|--ew|--get |--keys|--qcd|--show> +Usage: pineappl read <--orders|--orders-spaces|--orders-long|--bins|--channels|--fk-table|--fk-table-fac0|--fk-table-frg0|--ew|--get |--keys|--qcd|--show> For more information, try '--help'. "; @@ -631,12 +633,12 @@ fn orders_spaces() { } #[test] -fn fktable() { +fn fk_table() { Command::cargo_bin("pineappl") .unwrap() .args([ "read", - "--fktable", + "--fk-table", "../test-data/LHCB_WP_7TEV_opt.pineappl.lz4", ]) .assert() diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index f863159ff..69683cd24 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -173,15 +173,26 @@ impl PyFkTable { self.fk_table.channels() } - /// Get reference (fitting) scale. + /// Get squared factorization scale. /// /// Returns /// ------- /// float : - /// reference scale + /// squared factorization scale #[must_use] - pub fn muf2(&self) -> f64 { - self.fk_table.muf2() + pub fn fac0(&self) -> Option { + self.fk_table.fac0() + } + + /// Get squared fragmentation scale. + /// + /// Returns + /// ------- + /// float : + /// squared fragmentation scale + #[must_use] + pub fn frg0(&self) -> Option { + self.fk_table.frg0() } /// Get (unique) interpolation grid. diff --git a/pineappl_py/tests/test_fk_table.py b/pineappl_py/tests/test_fk_table.py index 4f01e25ce..2ab6ae273 100644 --- a/pineappl_py/tests/test_fk_table.py +++ b/pineappl_py/tests/test_fk_table.py @@ -77,7 +77,8 @@ def test_fktable( fk = FkTable.read(fk_table) assert fk.table().shape == (1, 51, 34, 34) - np.testing.assert_allclose(fk.muf2(), 2.7224999999999997) + np.testing.assert_allclose(fk.fac0(), 2.7224999999999997) + assert fk.frg0() == None # Check the various aspects of the Bins assert fk.bins() == 1