From b7b0accc4c0b6855c5c80afc6305a923889835be Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 5 Oct 2021 14:25:05 +0200 Subject: [PATCH 01/13] Add separe target pids for eko convolution --- pineappl/src/grid.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 6e49e442..a8644a9e 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -1141,6 +1141,7 @@ impl Grid { alphas: &[f64], (xir, xif): (f64, f64), pids: &[i32], + target_pids: &[i32], x_grid: Vec, q2_grid: Vec, operator: Array5, @@ -1178,7 +1179,6 @@ impl Grid { _ => unimplemented!(), }; - // create target luminosities let pids1 = if has_pdf1 { pids.to_vec() } else { @@ -1189,9 +1189,20 @@ impl Grid { } else { vec![initial_state_2] }; - let lumi: Vec<_> = pids1 + // create target luminosities + let tgt_pids1 = if has_pdf1 { + target_pids.to_vec() + } else { + vec![initial_state_1] + }; + let tgt_pids2 = if has_pdf2 { + target_pids.to_vec() + } else { + vec![initial_state_2] + }; + let lumi: Vec<_> = tgt_pids1 .iter() - .cartesian_product(pids2.iter()) + .cartesian_product(tgt_pids2.iter()) .map(|(a, b)| lumi_entry![*a, *b, 1.0]) .collect(); From 11963ebddd3be49f29cccd34ff0acbec4accd53a Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 5 Oct 2021 14:49:45 +0200 Subject: [PATCH 02/13] Sync python interface with pids update --- pineappl_py/pineappl/grid.py | 1 + pineappl_py/src/grid.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/pineappl_py/pineappl/grid.py b/pineappl_py/pineappl/grid.py index b9756952..12b0abeb 100644 --- a/pineappl_py/pineappl/grid.py +++ b/pineappl_py/pineappl/grid.py @@ -181,6 +181,7 @@ def convolute_eko(self, operators): operators["q2_ref"], alphas_values, operators["targetpids"], + operators["inputpids"], operators["interpolation_xgrid"], q2grid, operator_grid.flatten(), diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 9839c544..80c1131e 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -258,6 +258,7 @@ impl PyGrid { q2: f64, alphas: Vec, pids: Vec, + target_pids: Vec, x_grid: Vec, q2_grid: Vec, operator_flattened: Vec, @@ -271,6 +272,7 @@ impl PyGrid { &alphas, (1., 1.), &pids, + &target_pids, x_grid, q2_grid, operator.into_dimensionality::().unwrap(), From c42860c5477b3564cf0202f5f20ea0233afc35ef Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Tue, 5 Oct 2021 17:17:05 +0200 Subject: [PATCH 03/13] Allow additional metadata in FkTable generation --- pineappl/src/grid.rs | 5 +++++ pineappl_py/pineappl/grid.py | 7 ++++++- pineappl_py/src/grid.rs | 3 +++ pineappl_py/tests/test_grid.py | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index a8644a9e..70196604 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -1145,6 +1145,7 @@ impl Grid { x_grid: Vec, q2_grid: Vec, operator: Array5, + additional_metadata: HashMap, ) -> Option { // Check operator layout let dim = operator.shape(); @@ -1227,6 +1228,10 @@ impl Grid { subgrid_params: SubgridParams::default(), more_members: self.more_members.clone(), }; + // write additional metadata + for (key, value) in additional_metadata.iter() { + result.set_key_value(key, value); + } // collect source grid informations let eko_info = self.eko_info().unwrap(); diff --git a/pineappl_py/pineappl/grid.py b/pineappl_py/pineappl/grid.py index 12b0abeb..772bb3e1 100644 --- a/pineappl_py/pineappl/grid.py +++ b/pineappl_py/pineappl/grid.py @@ -155,7 +155,7 @@ def convolute( xfx1, xfx2, alphas, order_mask, bin_indices, lumi_mask, xi ) - def convolute_eko(self, operators): + def convolute_eko(self, operators, additional_metadata=None): """ Create an FKTable with the EKO. @@ -165,12 +165,16 @@ def convolute_eko(self, operators): ---------- operators : dict EKO Output + additional_metadata : dict + additional metadata Returns ------ PyFkTable : raw grid as an FKTable """ + if additional_metadata is None: + additional_metadata = {} operator_grid = np.array( [op["operators"] for op in operators["Q2grid"].values()] ) @@ -186,6 +190,7 @@ def convolute_eko(self, operators): q2grid, operator_grid.flatten(), operator_grid.shape, + additional_metadata, ) ) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 80c1131e..16c2d282 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -9,6 +9,7 @@ use ndarray::{Array, Ix5}; use std::fs::File; use std::io::BufReader; +use std::collections::HashMap; use pyo3::prelude::*; @@ -263,6 +264,7 @@ impl PyGrid { q2_grid: Vec, operator_flattened: Vec, operator_shape: Vec, + additional_metadata: HashMap, ) -> PyFkTable { let operator = Array::from_shape_vec(operator_shape, operator_flattened).unwrap(); let evolved_grid = self @@ -276,6 +278,7 @@ impl PyGrid { x_grid, q2_grid, operator.into_dimensionality::().unwrap(), + additional_metadata ) .unwrap(); PyFkTable { diff --git a/pineappl_py/tests/test_grid.py b/pineappl_py/tests/test_grid.py index 2c79e5ad..5248fd62 100644 --- a/pineappl_py/tests/test_grid.py +++ b/pineappl_py/tests/test_grid.py @@ -145,6 +145,6 @@ def test_convolute_eko(self): } } } - g.set_key_value("lumi_id_types", "PDG") + g.set_key_value("lumi_id_types", "pdg_mc_ids") fk = g.convolute_eko(fake_eko) assert isinstance(fk.raw, pineappl.pineappl.PyFkTable) From 3c52966c1de6103a7d9e87e3a1eb4bd71393af56 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 12 Oct 2021 17:44:52 +0200 Subject: [PATCH 04/13] Introduce new Eko related structs --- pineappl/src/grid.rs | 135 ++++++++++++++++++++++----------- pineappl_py/pineappl/grid.py | 3 +- pineappl_py/src/grid.rs | 65 +++++++++++----- pineappl_py/tests/test_grid.py | 10 ++- 4 files changed, 143 insertions(+), 70 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 70196604..b12c11d7 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -208,13 +208,35 @@ impl MoreMembers { /// Information required to compute a compatible EKO. /// Members spell out specific characteristic of a suitable EKO. -pub struct EkoInfo { +pub struct GridAxes { /// is the interpolation grid in x used at the process scale pub x_grid: Vec, + /// are the parton ids used in the process + pub pids: Vec, /// is the intepolation grid in q2, spanning the q2 range covered by the process data pub muf2_grid: Vec, } +/// Extra information required about an EKO to convolute to a Grid +pub struct EkoInfo { + /// scale for the FkTable + pub muf2_0: f64, + /// alpha_s vector + pub alphas: Vec, + /// renormalization scale variations ratio + pub xir: f64, + /// factorization scale variations ratio + pub xif: f64, + /// x_grid of the final FKTable + pub target_x_grid: Vec, + /// pids of the final FKTable + pub target_pids: Vec, + /// axes shared with the process grid + pub grid_axes: GridAxes, + /// further data to add + pub additional_metadata: HashMap, +} + /// Main data structure of `PineAPPL`. This structure contains a `Subgrid` for each `LumiEntry`, /// bin, and coupling order it was created with. #[derive(Deserialize, Serialize)] @@ -1066,9 +1088,10 @@ impl Grid { /// Provide information used to compute a suitable EKO for the current grid. /// More specific, the `x_grid` and `muf2_grid` are extracted and checked. #[must_use] - pub fn eko_info(&self) -> Option { + pub fn axes(&self) -> Option { let mut muf2_grid = Vec::::new(); let mut x_grid = Vec::::new(); + let pids = Vec::::new(); let mut has_pdf1 = true; let mut has_pdf2 = true; @@ -1123,7 +1146,11 @@ impl Grid { } } - Some(EkoInfo { x_grid, muf2_grid }) + Some(GridAxes { + x_grid, + pids, // TODO: for the time being they are just empty, but we might use them for slicing the eko + muf2_grid, + }) } /// Applies an evolution kernel operator (EKO) to the grids to evolve them from different @@ -1135,26 +1162,15 @@ impl Grid { /// /// Panics if the parameters do not match with the given grid. #[must_use] - pub fn convolute_eko( - &self, - q2: f64, - alphas: &[f64], - (xir, xif): (f64, f64), - pids: &[i32], - target_pids: &[i32], - x_grid: Vec, - q2_grid: Vec, - operator: Array5, - additional_metadata: HashMap, - ) -> Option { + pub fn convolute_eko(&self, operator: Array5, eko_info: EkoInfo) -> Option { // Check operator layout let dim = operator.shape(); - assert_eq!(dim[0], q2_grid.len()); - assert_eq!(dim[1], pids.len()); - assert_eq!(dim[2], x_grid.len()); - assert_eq!(dim[3], pids.len()); - assert_eq!(dim[4], x_grid.len()); + assert_eq!(dim[0], eko_info.grid_axes.muf2_grid.len()); + assert_eq!(dim[1], eko_info.target_pids.len()); + assert_eq!(dim[2], eko_info.target_x_grid.len()); + assert_eq!(dim[3], eko_info.grid_axes.pids.len()); + assert_eq!(dim[4], eko_info.grid_axes.x_grid.len()); // swap axes around to optimize convolution let operator = operator.permuted_axes([3, 1, 4, 0, 2]); @@ -1181,23 +1197,23 @@ impl Grid { }; let pids1 = if has_pdf1 { - pids.to_vec() + eko_info.grid_axes.pids.to_vec() } else { vec![initial_state_1] }; let pids2 = if has_pdf2 { - pids.to_vec() + eko_info.grid_axes.pids.to_vec() } else { vec![initial_state_2] }; // create target luminosities let tgt_pids1 = if has_pdf1 { - target_pids.to_vec() + eko_info.target_pids.to_vec() } else { vec![initial_state_1] }; let tgt_pids2 = if has_pdf2 { - target_pids.to_vec() + eko_info.target_pids.to_vec() } else { vec![initial_state_2] }; @@ -1208,9 +1224,17 @@ impl Grid { .collect(); // create target subgrid dimensions - let tgt_q2_grid = vec![q2]; - let tgt_x1_grid = if has_pdf1 { x_grid.clone() } else { vec![1.0] }; - let tgt_x2_grid = if has_pdf2 { x_grid.clone() } else { vec![1.0] }; + let tgt_q2_grid = vec![eko_info.muf2_0]; + let tgt_x1_grid = if has_pdf1 { + eko_info.target_x_grid.clone() + } else { + vec![1.0] + }; + let tgt_x2_grid = if has_pdf2 { + eko_info.target_x_grid.clone() + } else { + vec![1.0] + }; // create target grid let mut result = Self { @@ -1229,12 +1253,12 @@ impl Grid { more_members: self.more_members.clone(), }; // write additional metadata - for (key, value) in additional_metadata.iter() { + for (key, value) in eko_info.additional_metadata.iter() { result.set_key_value(key, value); } // collect source grid informations - let eko_info = self.eko_info().unwrap(); + let grid_axes = self.axes().unwrap(); // Setup progress bar let bar = ProgressBar::new( @@ -1264,22 +1288,26 @@ impl Grid { let mut src_array = SparseArray3::::new( src_array_q2_grid.len(), - if has_pdf1 { eko_info.x_grid.len() } else { 1 }, - if has_pdf2 { eko_info.x_grid.len() } else { 1 }, + if has_pdf1 { grid_axes.x_grid.len() } else { 1 }, + if has_pdf2 { grid_axes.x_grid.len() } else { 1 }, ); // iterate over the source grid orders and add all of them together into // `src_array`, using the right powers of alphas for (order, powers) in self.orders.iter().enumerate() { - let logs = if (xir, xif) == (1.0, 1.0) { + let logs = if (eko_info.xir, eko_info.xif) == (1.0, 1.0) { if (powers.logxir > 0) || (powers.logxif > 0) { continue; } 1.0 } else { - (xir * xir).ln().powi(powers.logxir.try_into().unwrap()) - * (xif * xif).ln().powi(powers.logxif.try_into().unwrap()) + (eko_info.xir * eko_info.xir) + .ln() + .powi(powers.logxir.try_into().unwrap()) + * (eko_info.xif * eko_info.xif) + .ln() + .powi(powers.logxif.try_into().unwrap()) }; let src_subgrid = &self.subgrids[[order, bin, src_lumi]]; @@ -1289,13 +1317,13 @@ impl Grid { && !src_subgrid .x1_grid() .iter() - .zip(x_grid.iter()) + .zip(eko_info.grid_axes.x_grid.iter()) .all(|(a, b)| approx_eq!(f64, *a, *b, ulps = 128))) || (has_pdf2 && !src_subgrid .x2_grid() .iter() - .zip(x_grid.iter()) + .zip(eko_info.grid_axes.x_grid.iter()) .all(|(a, b)| approx_eq!(f64, *a, *b, ulps = 128))); for ((iq2, ix1, ix2), &value) in src_subgrid.iter() { @@ -1304,24 +1332,28 @@ impl Grid { .iter() .position(|&q2| q2 == scale) .unwrap(); - let als_iq2 = q2_grid + let als_iq2 = eko_info + .grid_axes + .muf2_grid .iter() - .position(|&q2| q2 == xir * xir * scale) + .position(|&q2| q2 == eko_info.xir * eko_info.xir * scale) .unwrap(); let ix1 = if invert_x && has_pdf1 { - eko_info.x_grid.len() - ix1 - 1 + eko_info.grid_axes.x_grid.len() - ix1 - 1 } else { ix1 }; let ix2 = if invert_x && has_pdf2 { - eko_info.x_grid.len() - ix2 - 1 + eko_info.grid_axes.x_grid.len() - ix2 - 1 } else { ix2 }; - src_array[[src_iq2, ix1, ix2]] += - alphas[als_iq2].powi(powers.alphas.try_into().unwrap()) * logs * value; + src_array[[src_iq2, ix1, ix2]] += eko_info.alphas[als_iq2] + .powi(powers.alphas.try_into().unwrap()) + * logs + * value; } } @@ -1336,7 +1368,14 @@ impl Grid { // Next we need to apply the tensor let eko_src_q2_indices: Vec<_> = src_array_q2_grid .iter() - .map(|&src_q2| q2_grid.iter().position(|&q2| q2 == src_q2).unwrap()) + .map(|&src_q2| { + eko_info + .grid_axes + .muf2_grid + .iter() + .position(|&q2| q2 == src_q2) + .unwrap() + }) .collect(); // Iterate target lumis for (tgt_lumi, (tgt_pid1_idx, tgt_pid2_idx)) in (0..pids1.len()) @@ -1346,7 +1385,10 @@ impl Grid { for (src_pid1, src_pid2, factor) in src_entries.entry().iter() { // find source lumi position let src_pid1_idx = if has_pdf1 { - pids.iter() + eko_info + .grid_axes + .pids + .iter() .position(|x| { // if `pid == 0` the gluon is meant if *src_pid1 == 0 { @@ -1360,7 +1402,10 @@ impl Grid { 0 }; let src_pid2_idx = if has_pdf2 { - pids.iter() + eko_info + .grid_axes + .pids + .iter() .position(|x| { // `pid == 0` is the gluon exception, which might be 0 or 21 if *src_pid2 == 0 { diff --git a/pineappl_py/pineappl/grid.py b/pineappl_py/pineappl/grid.py index 772bb3e1..d0789100 100644 --- a/pineappl_py/pineappl/grid.py +++ b/pineappl_py/pineappl/grid.py @@ -185,8 +185,9 @@ def convolute_eko(self, operators, additional_metadata=None): operators["q2_ref"], alphas_values, operators["targetpids"], + operators["targetgrid"], operators["inputpids"], - operators["interpolation_xgrid"], + operators["inputgrid"], q2grid, operator_grid.flatten(), operator_grid.shape, diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 16c2d282..c02e6d0f 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -1,4 +1,4 @@ -use pineappl::grid::{EkoInfo, Grid, Ntuple, Order}; +use pineappl::grid::{EkoInfo, Grid, GridAxes, Ntuple, Order}; use super::bin::PyBinRemapper; use super::fk_table::PyFkTable; @@ -7,9 +7,9 @@ use super::subgrid::{PySubgridEnum, PySubgridParams}; use ndarray::{Array, Ix5}; +use std::collections::HashMap; use std::fs::File; use std::io::BufReader; -use std::collections::HashMap; use pyo3::prelude::*; @@ -167,11 +167,17 @@ impl PyGrid { /// ------- /// x_grid: list(float) /// interpolation grid + /// pids: list(int) + /// particle ids /// muf2_grid : list(float) /// factorization scale list - pub fn eko_info(&self) -> (Vec, Vec) { - let EkoInfo { x_grid, muf2_grid } = self.grid.eko_info().unwrap(); - (x_grid, muf2_grid) + pub fn axes(&self) -> (Vec, Vec, Vec) { + let GridAxes { + x_grid, + pids, + muf2_grid, + } = self.grid.axes().unwrap(); + (x_grid, pids, muf2_grid) } /// Convolute grid with pdf. @@ -235,7 +241,7 @@ impl PyGrid { /// /// Parameters /// ---------- - /// q2 : float + /// muf2_0 : float /// reference scale /// alphas : list(float) /// list with :math:`\alpha_s(Q2)` for the process scales @@ -243,12 +249,18 @@ impl PyGrid { /// sorting of the particles in the tensor /// x_grid : list(float) /// interpolation grid - /// q2_grid : list(float) + /// target_pids : list(int) + /// sorting of the particles in the tensor for final FkTable + /// target_x_grid : list(float) + /// final FKTable interpolation grid + /// muf2_grid : list(float) /// list of process scales /// operator_flattened : list(float) /// evolution tensor as a flat list /// operator_shape : list(int) /// shape of the evolution tensor + /// additional_metadata : dict(str: str) + /// further metadata /// /// Returns /// ------- @@ -256,30 +268,36 @@ impl PyGrid { /// produced FK table pub fn convolute_eko( &self, - q2: f64, + muf2_0: f64, alphas: Vec, pids: Vec, - target_pids: Vec, x_grid: Vec, - q2_grid: Vec, + target_pids: Vec, + target_x_grid: Vec, + muf2_grid: Vec, operator_flattened: Vec, operator_shape: Vec, additional_metadata: HashMap, ) -> PyFkTable { let operator = Array::from_shape_vec(operator_shape, operator_flattened).unwrap(); + let eko_info = EkoInfo { + muf2_0, + alphas, + xir: 0., + xif: 0., + target_pids, + target_x_grid, + grid_axes: GridAxes { + x_grid, + pids, + muf2_grid, + }, + additional_metadata, + }; + let evolved_grid = self .grid - .convolute_eko( - q2, - &alphas, - (1., 1.), - &pids, - &target_pids, - x_grid, - q2_grid, - operator.into_dimensionality::().unwrap(), - additional_metadata - ) + .convolute_eko(operator.into_dimensionality::().unwrap(), eko_info) .unwrap(); PyFkTable { fk_table: evolved_grid, @@ -323,6 +341,11 @@ impl PyGrid { self.grid.optimize(); } + /// Optimize grid content. + // pub fn merge(&mut self, mut other: Self) { + // self.grid.merge(other.grid); + // } + /// Extract the number of dimensions for bins. /// /// **Usage:** `pineko` diff --git a/pineappl_py/tests/test_grid.py b/pineappl_py/tests/test_grid.py index 5248fd62..4c7cccb5 100644 --- a/pineappl_py/tests/test_grid.py +++ b/pineappl_py/tests/test_grid.py @@ -97,7 +97,7 @@ def test_convolute(self): np.testing.assert_allclose(g.convolute(lambda pid,x,q2: 1, lambda pid,x,q2: 1., lambda q2: 1.), [5e6/9999,0.]) np.testing.assert_allclose(g.convolute(lambda pid,x,q2: 1, lambda pid,x,q2: 1., lambda q2: 2.), [2**3 * 5e6/9999,0.]) - def test_eko_info(self): + def test_axes(self): g = self.fake_grid() # add 2 DIS grids @@ -119,10 +119,11 @@ def test_eko_info(self): ) g.set_subgrid(0, 1, 0, subgrid) # now get the thing - ei = g.eko_info() + ei = g.axes() np.testing.assert_allclose(ei[0], xs) - np.testing.assert_allclose(ei[1], [90., 100.]) + np.testing.assert_allclose(ei[1], []) + np.testing.assert_allclose(ei[2], [90., 100.]) def test_io(self, tmp_path): g = self.fake_grid() @@ -137,6 +138,9 @@ def test_convolute_eko(self): fake_eko = { "q2_ref": 1., "targetpids": [1], + "targetgrid": [.1,1.], + "inputpids": [1], + "inputgrid": [.1,1.], "interpolation_xgrid": [.1,1.], "Q2grid": { 90: { From 45963f45d1b1bfb37476d902f201fbdcd7597038 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Tue, 12 Oct 2021 18:21:18 +0200 Subject: [PATCH 05/13] Improve documentation strings --- pineappl/src/grid.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index b12c11d7..8768f8e0 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -206,34 +206,36 @@ impl MoreMembers { } } -/// Information required to compute a compatible EKO. -/// Members spell out specific characteristic of a suitable EKO. +/// Information required to calculate the evolution kernel operators (EKO) to perform a conversion +/// of a [`Grid`] using [`Grid::convolute_eko`] to an [`FkTable`]. pub struct GridAxes { - /// is the interpolation grid in x used at the process scale + /// Interpolation grid in x of the `Grid`. pub x_grid: Vec, - /// are the parton ids used in the process + /// Parton IDs used in the grid. pub pids: Vec, - /// is the intepolation grid in q2, spanning the q2 range covered by the process data + /// Interpolation grid for the factorization scale of the `Grid`. pub muf2_grid: Vec, } -/// Extra information required about an EKO to convolute to a Grid +/// Extra information required to perform the conversion of a [`Grid`] to an [`FkTable`] using +/// [`Grid::convolute_eko`]. pub struct EkoInfo { - /// scale for the FkTable + /// Scale of the FkTable. pub muf2_0: f64, - /// alpha_s vector + /// Strong coupling constants for the factorization scales in the same ordering as given in + /// [`GridAxes`]. pub alphas: Vec, - /// renormalization scale variations ratio + /// Renormalization scale variation. pub xir: f64, - /// factorization scale variations ratio + /// Factorization scale variation. pub xif: f64, - /// x_grid of the final FKTable + /// Interpolation grid in x of the `FkTable`. pub target_x_grid: Vec, - /// pids of the final FKTable + /// Parton IDs for the `FkTable`. pub target_pids: Vec, /// axes shared with the process grid pub grid_axes: GridAxes, - /// further data to add + // TODO: replace this member with the actual data pub additional_metadata: HashMap, } From d4a9155057ae44d9e4dcceda40055e6fc97e3421 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Wed, 13 Oct 2021 17:01:28 +0200 Subject: [PATCH 06/13] Add temporary axes test --- pineappl/src/grid.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 8768f8e0..ea3ab703 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -1778,4 +1778,38 @@ mod tests { "-2212" ); } + + // TODO: properly test axes returned + + #[test] + fn grid_axes() { + let mut grid = Grid::new( + vec![lumi_entry![21, 21, 1.0], lumi_entry![1, 2, 1.0]], + vec![Order { + alphas: 0, + alpha: 0, + logxir: 0, + logxif: 0, + }], + vec![0.0, 1.0], + SubgridParams::default(), + ); + + grid.fill( + 0, + 0.5, + 0, + &Ntuple { + x1: 0.1, + x2: 0.1, + q2: 20., + weight: 1., + }, + ); + + let axes = grid.axes().unwrap(); + assert_eq!(axes.x_grid, vec![]); + assert_eq!(axes.muf2_grid, vec![]); + assert_eq!(axes.pids, vec![]); + } } From 8bbdb3ccf50e775e7da361c939cf42f9ee58c373 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Thu, 14 Oct 2021 02:23:51 +0200 Subject: [PATCH 07/13] Add broken test for convolute_eko --- pineappl/src/grid.rs | 66 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index ea3ab703..19c8ff38 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -15,7 +15,7 @@ use git_version::git_version; use indicatif::{ProgressBar, ProgressStyle}; use itertools::Itertools; use lz_fear::{framed::DecompressionError::WrongMagic, LZ4FrameReader}; -use ndarray::{s, Array3, Array5, Dimension}; +use ndarray::{s, Array, Array2, Array3, Array5, Dimension}; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use std::borrow::Cow; @@ -235,7 +235,7 @@ pub struct EkoInfo { pub target_pids: Vec, /// axes shared with the process grid pub grid_axes: GridAxes, - // TODO: replace this member with the actual data + /// TODO: replace this member with the actual data pub additional_metadata: HashMap, } @@ -1781,9 +1781,18 @@ mod tests { // TODO: properly test axes returned - #[test] - fn grid_axes() { - let mut grid = Grid::new( + fn simple_grid() -> Grid { + let mut subgrid_params = SubgridParams::default(); + subgrid_params.set_x_order(1); + subgrid_params.set_x_bins(1); + subgrid_params.set_q2_order(1); + subgrid_params.set_q2_bins(1); + + let mut extra = ExtraSubgridParams::default(); + extra.set_x2_order(1); + extra.set_x2_bins(1); + + let mut grid = Grid::with_subgrid_type( vec![lumi_entry![21, 21, 1.0], lumi_entry![1, 2, 1.0]], vec![Order { alphas: 0, @@ -1792,8 +1801,11 @@ mod tests { logxif: 0, }], vec![0.0, 1.0], - SubgridParams::default(), - ); + subgrid_params, + extra, + "LagrangeSubgrid", + ) + .unwrap(); grid.fill( 0, @@ -1807,9 +1819,49 @@ mod tests { }, ); + grid + } + + #[test] + fn grid_axes() { + let grid = simple_grid(); + let axes = grid.axes().unwrap(); assert_eq!(axes.x_grid, vec![]); assert_eq!(axes.muf2_grid, vec![]); assert_eq!(axes.pids, vec![]); } + + #[test] + fn grid_convolute_eko() { + let grid = simple_grid(); + + let eko_info = EkoInfo { + muf2_0: 1., + alphas: vec![1.], + xir: 1., + xif: 1., + target_x_grid: vec![1.], + target_pids: vec![21, 1, 2], + grid_axes: GridAxes { + x_grid: vec![1.], + pids: vec![21, 1, 2], + muf2_grid: vec![1.], + }, + additional_metadata: HashMap::new(), + }; + let id = Array2::::eye(3); + let operator = Array::from_shape_vec( + (1, 3, 1, 3, 1), + id.clone() + .into_iter() + // .cartesian_product(id.iter()) + // .map(|(i, j)| i * j) + .collect(), + ) + .unwrap(); + let fk = grid.convolute_eko(operator, eko_info).unwrap(); + + assert_eq!(fk.bins(), 1); + } } From be69003862ece36cfc71bbce73af948d44e7e602 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Fri, 15 Oct 2021 09:24:20 +0200 Subject: [PATCH 08/13] Fix convolute_eko test --- pineappl/src/grid.rs | 87 ++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 19c8ff38..578212d2 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -1781,18 +1781,29 @@ mod tests { // TODO: properly test axes returned - fn simple_grid() -> Grid { + fn simple_grid() -> (Grid, GridAxes) { + let muf2_grid = vec![20.]; + let x_grid = vec![0.1, 0.5, 1.]; + let mut subgrid_params = SubgridParams::default(); subgrid_params.set_x_order(1); subgrid_params.set_x_bins(1); subgrid_params.set_q2_order(1); subgrid_params.set_q2_bins(1); - let mut extra = ExtraSubgridParams::default(); - extra.set_x2_order(1); - extra.set_x2_bins(1); + let mut array = Array3::zeros((1, 3, 3)); + array[[0, 0, 0]] = 1.; + let sparse_array = SparseArray3::from_ndarray(&array, 0, 3); + let subgrid = ImportOnlySubgridV1::new( + sparse_array, + muf2_grid.clone(), + x_grid.clone(), + x_grid.clone(), + ) + .into(); - let mut grid = Grid::with_subgrid_type( + let pids = vec![21, 1, 2]; + let mut grid = Grid::new( vec![lumi_entry![21, 21, 1.0], lumi_entry![1, 2, 1.0]], vec![Order { alphas: 0, @@ -1802,61 +1813,59 @@ mod tests { }], vec![0.0, 1.0], subgrid_params, - extra, - "LagrangeSubgrid", - ) - .unwrap(); - - grid.fill( - 0, - 0.5, - 0, - &Ntuple { - x1: 0.1, - x2: 0.1, - q2: 20., - weight: 1., - }, ); - grid + grid.set_subgrid(0, 0, 0, subgrid); + + ( + grid, + GridAxes { + x_grid, + pids, + muf2_grid, + }, + ) } #[test] fn grid_axes() { - let grid = simple_grid(); + let (grid, axes) = simple_grid(); - let axes = grid.axes().unwrap(); - assert_eq!(axes.x_grid, vec![]); - assert_eq!(axes.muf2_grid, vec![]); - assert_eq!(axes.pids, vec![]); + let ret_axes = grid.axes().unwrap(); + assert_eq!(ret_axes.x_grid, axes.x_grid); + assert_eq!(ret_axes.muf2_grid, axes.muf2_grid); + assert_eq!(ret_axes.pids, vec![]); } #[test] fn grid_convolute_eko() { - let grid = simple_grid(); + let (grid, axes) = simple_grid(); + let target_x_grid = vec![1e-7, 1e-2, 1.]; + let target_pids = vec![21, 1, 2]; + + let mut additional_metadata = HashMap::new(); + additional_metadata.insert("lumi_id_types".to_owned(), "pdg_mc_ids".to_owned()); let eko_info = EkoInfo { muf2_0: 1., alphas: vec![1.], xir: 1., xif: 1., - target_x_grid: vec![1.], - target_pids: vec![21, 1, 2], + target_x_grid: target_x_grid.clone(), + target_pids: target_pids.clone(), grid_axes: GridAxes { - x_grid: vec![1.], - pids: vec![21, 1, 2], - muf2_grid: vec![1.], + x_grid: axes.x_grid.clone(), + pids: axes.pids.clone(), + muf2_grid: axes.muf2_grid.clone(), }, - additional_metadata: HashMap::new(), + additional_metadata, }; - let id = Array2::::eye(3); let operator = Array::from_shape_vec( - (1, 3, 1, 3, 1), - id.clone() - .into_iter() - // .cartesian_product(id.iter()) - // .map(|(i, j)| i * j) + (1, 3, 3, 3, 3), + (0..4) + .map(|_| (0..3)) + .multi_cartesian_product() + .map(|v| if v[0] == v[2] && v[1] == v[3] { 1. } else { 0. }) .collect(), ) .unwrap(); From 9b634e56416fc15f5e47b67eb85ab2898d047079 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Fri, 15 Oct 2021 10:26:30 +0200 Subject: [PATCH 09/13] Remove the too flexible additional metadata from EkoInfo --- pineappl/src/grid.rs | 15 ++++++--------- pineappl_py/pineappl/grid.py | 6 ++---- pineappl_py/src/grid.rs | 5 ++--- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 578212d2..140c9855 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -15,7 +15,7 @@ use git_version::git_version; use indicatif::{ProgressBar, ProgressStyle}; use itertools::Itertools; use lz_fear::{framed::DecompressionError::WrongMagic, LZ4FrameReader}; -use ndarray::{s, Array, Array2, Array3, Array5, Dimension}; +use ndarray::{s, Array3, Array5, Dimension}; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use std::borrow::Cow; @@ -236,7 +236,7 @@ pub struct EkoInfo { /// axes shared with the process grid pub grid_axes: GridAxes, /// TODO: replace this member with the actual data - pub additional_metadata: HashMap, + pub lumi_id_types: String, } /// Main data structure of `PineAPPL`. This structure contains a `Subgrid` for each `LumiEntry`, @@ -1255,9 +1255,7 @@ impl Grid { more_members: self.more_members.clone(), }; // write additional metadata - for (key, value) in eko_info.additional_metadata.iter() { - result.set_key_value(key, value); - } + result.set_key_value("lumi_id_types", &eko_info.lumi_id_types); // collect source grid informations let grid_axes = self.axes().unwrap(); @@ -1843,8 +1841,7 @@ mod tests { let target_x_grid = vec![1e-7, 1e-2, 1.]; let target_pids = vec![21, 1, 2]; - let mut additional_metadata = HashMap::new(); - additional_metadata.insert("lumi_id_types".to_owned(), "pdg_mc_ids".to_owned()); + let lumi_id_types = "pdg_mc_ids".to_owned(); let eko_info = EkoInfo { muf2_0: 1., @@ -1858,9 +1855,9 @@ mod tests { pids: axes.pids.clone(), muf2_grid: axes.muf2_grid.clone(), }, - additional_metadata, + lumi_id_types, }; - let operator = Array::from_shape_vec( + let operator = ndarray::Array::from_shape_vec( (1, 3, 3, 3, 3), (0..4) .map(|_| (0..3)) diff --git a/pineappl_py/pineappl/grid.py b/pineappl_py/pineappl/grid.py index d0789100..7aa91df6 100644 --- a/pineappl_py/pineappl/grid.py +++ b/pineappl_py/pineappl/grid.py @@ -155,7 +155,7 @@ def convolute( xfx1, xfx2, alphas, order_mask, bin_indices, lumi_mask, xi ) - def convolute_eko(self, operators, additional_metadata=None): + def convolute_eko(self, operators, lumi_id_types="pdg_mc_ids"): """ Create an FKTable with the EKO. @@ -173,8 +173,6 @@ def convolute_eko(self, operators, additional_metadata=None): PyFkTable : raw grid as an FKTable """ - if additional_metadata is None: - additional_metadata = {} operator_grid = np.array( [op["operators"] for op in operators["Q2grid"].values()] ) @@ -191,7 +189,7 @@ def convolute_eko(self, operators, additional_metadata=None): q2grid, operator_grid.flatten(), operator_grid.shape, - additional_metadata, + lumi_id_types, ) ) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index c02e6d0f..78dc844f 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -7,7 +7,6 @@ use super::subgrid::{PySubgridEnum, PySubgridParams}; use ndarray::{Array, Ix5}; -use std::collections::HashMap; use std::fs::File; use std::io::BufReader; @@ -277,7 +276,7 @@ impl PyGrid { muf2_grid: Vec, operator_flattened: Vec, operator_shape: Vec, - additional_metadata: HashMap, + lumi_id_types: String, ) -> PyFkTable { let operator = Array::from_shape_vec(operator_shape, operator_flattened).unwrap(); let eko_info = EkoInfo { @@ -292,7 +291,7 @@ impl PyGrid { pids, muf2_grid, }, - additional_metadata, + lumi_id_types, }; let evolved_grid = self From 4e19962e44efad27a7ea2624841f3ba6246cf4d8 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Mon, 18 Oct 2021 12:43:03 +0200 Subject: [PATCH 10/13] Fix bug in conv_eko, expose optimize --- pineappl/src/fk_table.rs | 9 +++++++++ pineappl/src/grid.rs | 5 ++++- pineappl_py/src/fk_table.rs | 8 ++++++++ pineappl_py/src/grid.rs | 4 ++-- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/pineappl/src/fk_table.rs b/pineappl/src/fk_table.rs index 3783387e..42305e02 100644 --- a/pineappl/src/fk_table.rs +++ b/pineappl/src/fk_table.rs @@ -136,6 +136,15 @@ impl FkTable { self.grid.write(writer) } + /// Optimize grid + /// + /// # Errors + /// + /// TODO + pub fn optimize(&mut self) { + self.grid.optimize() + } + /// Propagate convolute to grid pub fn convolute( &self, diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 140c9855..961c53f8 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -1337,7 +1337,10 @@ impl Grid { .muf2_grid .iter() .position(|&q2| q2 == eko_info.xir * eko_info.xir * scale) - .unwrap(); + .expect(&format!( + "Couldn't find q2: {:?} with xir: {:?} and muf2_grid: {:?}", + scale, eko_info.xir, eko_info.grid_axes.muf2_grid + )); let ix1 = if invert_x && has_pdf1 { eko_info.grid_axes.x_grid.len() - ix1 - 1 diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index 1577bdf6..82e21f41 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -89,6 +89,14 @@ impl PyFkTable { self.fk_table.write(File::create(path).unwrap()).unwrap(); } + /// Optimize grid. + /// + /// **Usage:** `pineko` + /// + pub fn optimize(&mut self) { + self.fk_table.optimize(); + } + /// Convolute grid with pdf. /// /// **Usage:** `pineko` diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 78dc844f..417d63c7 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -282,8 +282,8 @@ impl PyGrid { let eko_info = EkoInfo { muf2_0, alphas, - xir: 0., - xif: 0., + xir: 1., + xif: 1., target_pids, target_x_grid, grid_axes: GridAxes { From 809e933932eea53a7fe7abdab7f9c91f92c5cd96 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 18 Oct 2021 14:31:54 +0200 Subject: [PATCH 11/13] Update lumi_id_types docstring --- pineappl_py/pineappl/grid.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pineappl_py/pineappl/grid.py b/pineappl_py/pineappl/grid.py index 7aa91df6..0a6158c0 100644 --- a/pineappl_py/pineappl/grid.py +++ b/pineappl_py/pineappl/grid.py @@ -165,8 +165,9 @@ def convolute_eko(self, operators, lumi_id_types="pdg_mc_ids"): ---------- operators : dict EKO Output - additional_metadata : dict - additional metadata + lumi_id_types : str + kind of lumi types (e.g. "pdg_mc_ids" for flavor basis, "evol" + for evolution basis) Returns ------ From 2c0c64fce4723380786e29a50817383aa00cd064 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 18 Oct 2021 14:55:01 +0200 Subject: [PATCH 12/13] Always optimize FkTables --- pineappl/src/fk_table.rs | 9 --------- pineappl/src/grid.rs | 1 + 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/pineappl/src/fk_table.rs b/pineappl/src/fk_table.rs index 42305e02..3783387e 100644 --- a/pineappl/src/fk_table.rs +++ b/pineappl/src/fk_table.rs @@ -136,15 +136,6 @@ impl FkTable { self.grid.write(writer) } - /// Optimize grid - /// - /// # Errors - /// - /// TODO - pub fn optimize(&mut self) { - self.grid.optimize() - } - /// Propagate convolute to grid pub fn convolute( &self, diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 961c53f8..121b6f77 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -1507,6 +1507,7 @@ impl Grid { bar.finish(); + result.optimize(); Some(FkTable::try_from(result).unwrap()) } } From c422fb62976d261156b8f689a889464625379c25 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 18 Oct 2021 15:08:11 +0200 Subject: [PATCH 13/13] Remove FkTable.optimize even from python interface --- pineappl_py/src/fk_table.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index 82e21f41..1577bdf6 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -89,14 +89,6 @@ impl PyFkTable { self.fk_table.write(File::create(path).unwrap()).unwrap(); } - /// Optimize grid. - /// - /// **Usage:** `pineko` - /// - pub fn optimize(&mut self) { - self.fk_table.optimize(); - } - /// Convolute grid with pdf. /// /// **Usage:** `pineko`