diff --git a/pineappl/src/empty_subgrid.rs b/pineappl/src/empty_subgrid.rs index 8c08d0ff..93e9778b 100644 --- a/pineappl/src/empty_subgrid.rs +++ b/pineappl/src/empty_subgrid.rs @@ -18,6 +18,10 @@ impl Subgrid for EmptySubgridV1 { Vec::new() } + fn shape(&mut self) -> &[usize] { + panic!("EmptySubgridV1 doesn't have a shape"); + } + fn is_empty(&self) -> bool { true } @@ -103,4 +107,10 @@ mod tests { fn node_values() { assert!(EmptySubgridV1.node_values().is_empty()); } + + #[test] + #[should_panic(expected = "EmptySubgridV1 doesn't have a shape")] + fn shape() { + let _ = EmptySubgridV1.shape(); + } } diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index d2179aef..946a5a33 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -205,6 +205,12 @@ impl Grid { &mut self.pid_basis } + /// Return a vector containing the interpolation specifications for this grid. + #[must_use] + pub fn interpolations(&self) -> &[Interp] { + &self.interps + } + /// Return a vector containing the kinematic specifications for this grid. #[must_use] pub fn kinematics(&self) -> &[Kinematics] { @@ -1535,9 +1541,36 @@ mod tests { use crate::boc::ScaleFuncForm; use crate::channel; use crate::convolutions::ConvType; + use crate::interpolation::Map; use float_cmp::assert_approx_eq; use std::fs::File; + #[test] + fn interpolations() { + let grid = Grid::new( + PidBasis::Pdg, + vec![Channel::new(vec![(vec![1, -1], 1.0), (vec![2, -2], 1.0)])], + vec![Order::new(0, 2, 0, 0, 0)], + vec![0.0, 1.0], + vec![ + Conv::new(ConvType::UnpolPDF, 2212), + Conv::new(ConvType::UnpolPDF, 2212), + ], + v0::default_interps(2), + vec![Kinematics::Scale(0), Kinematics::X(0), Kinematics::X(1)], + Scales { + ren: ScaleFuncForm::Scale(0), + fac: ScaleFuncForm::Scale(0), + frg: ScaleFuncForm::NoScale, + }, + ); + + let interps = grid.interpolations(); + assert!(matches!(interps[0].map(), Map::ApplGridH0)); + assert!(matches!(interps[1].map(), Map::ApplGridF2)); + assert!(matches!(interps[2].map(), Map::ApplGridF2)); + } + #[test] #[should_panic(expected = "channel #0 has wrong number of PIDs: expected 2, found 3")] fn grid_new_panic0() { diff --git a/pineappl/src/import_subgrid.rs b/pineappl/src/import_subgrid.rs index 7e796e01..93c5b2aa 100644 --- a/pineappl/src/import_subgrid.rs +++ b/pineappl/src/import_subgrid.rs @@ -112,6 +112,10 @@ impl Subgrid for ImportSubgridV1 { Box::new(self.array.indexed_iter()) } + fn shape(&mut self) -> &[usize] { + self.array.shape() + } + fn stats(&self) -> Stats { Stats { total: self.array.shape().iter().product(), diff --git a/pineappl/src/interp_subgrid.rs b/pineappl/src/interp_subgrid.rs index 93705ac3..d8db341c 100644 --- a/pineappl/src/interp_subgrid.rs +++ b/pineappl/src/interp_subgrid.rs @@ -52,6 +52,10 @@ impl Subgrid for InterpSubgridV1 { self.array.is_empty() } + fn shape(&mut self) -> &[usize] { + self.array.shape() + } + fn merge(&mut self, other: &SubgridEnum, transpose: Option<(usize, usize)>) { // we cannot use `Self::indexed_iter` because it multiplies with `reweight` if let SubgridEnum::InterpSubgridV1(other) = other { @@ -261,5 +265,7 @@ mod tests { assert_eq!(node_values[0].len(), 23); assert_eq!(node_values[1].len(), 1); assert_eq!(node_values[2].len(), 1); + + assert_eq!(subgrid.shape(), [23, 1, 1]); } } diff --git a/pineappl/src/subgrid.rs b/pineappl/src/subgrid.rs index 21836dca..24f11cb4 100644 --- a/pineappl/src/subgrid.rs +++ b/pineappl/src/subgrid.rs @@ -74,6 +74,9 @@ pub trait Subgrid { /// Scale the subgrid by `factor`. fn scale(&mut self, factor: f64); + /// Return the shape of the subgrid + fn shape(&mut self) -> &[usize]; + /// Assume that the convolution functions for indices `a` and `b` for this grid are the same /// and use this to optimize the size of the grid. fn symmetrize(&mut self, a: usize, b: usize);