From be2b473e97e81e1ec79f94a044452eb4b125ddb7 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Tue, 6 Aug 2024 09:16:08 +0200 Subject: [PATCH 01/51] removes pineappl_py/pineappl layer --- pineappl_py/pineappl/__init__.py | 2 - pineappl_py/pineappl/bin.py | 20 - pineappl_py/pineappl/fk_table.py | 68 ---- pineappl_py/pineappl/grid.py | 392 -------------------- pineappl_py/pineappl/import_only_subgrid.py | 48 --- pineappl_py/pineappl/lumi.py | 16 - pineappl_py/pineappl/subgrid.py | 16 - pineappl_py/pineappl/utils.py | 19 - 8 files changed, 581 deletions(-) delete mode 100644 pineappl_py/pineappl/__init__.py delete mode 100644 pineappl_py/pineappl/bin.py delete mode 100644 pineappl_py/pineappl/fk_table.py delete mode 100644 pineappl_py/pineappl/grid.py delete mode 100644 pineappl_py/pineappl/import_only_subgrid.py delete mode 100644 pineappl_py/pineappl/lumi.py delete mode 100644 pineappl_py/pineappl/subgrid.py delete mode 100644 pineappl_py/pineappl/utils.py diff --git a/pineappl_py/pineappl/__init__.py b/pineappl_py/pineappl/__init__.py deleted file mode 100644 index 6b35e9540..000000000 --- a/pineappl_py/pineappl/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .pineappl import version as __version__ -from . import bin, fk_table, grid, import_only_subgrid, lumi, subgrid diff --git a/pineappl_py/pineappl/bin.py b/pineappl_py/pineappl/bin.py deleted file mode 100644 index 99395ac8e..000000000 --- a/pineappl_py/pineappl/bin.py +++ /dev/null @@ -1,20 +0,0 @@ -import numpy as np - -from .pineappl import PyBinRemapper -from .utils import PyWrapper - - -class BinRemapper(PyWrapper): - """ - Python wrapper object for :class:`~pineappl.pineappl.PyBinRemapper`. - - Parameters - ---------- - normalizations : sequence(float) - list with normalizations - limits : list(tuple(float,float)) - all bin limits as a flat list - """ - - def __init__(self, normalizations, limits): - self._raw = PyBinRemapper(np.array(normalizations), limits) diff --git a/pineappl_py/pineappl/fk_table.py b/pineappl_py/pineappl/fk_table.py deleted file mode 100644 index 2634a523f..000000000 --- a/pineappl_py/pineappl/fk_table.py +++ /dev/null @@ -1,68 +0,0 @@ -from .pineappl import PyFkTable, PyFkAssumptions -from .utils import PyWrapper - - -class FkTable(PyWrapper): - """Python wrapper object to interface - :class:`~pineappl.pineappl.PyFkTable`. - - Parameters - ---------- - pyfktable : PyFkTable - raw wrapper object - """ - - def __init__(self, pyfktable): - self._raw = pyfktable - - @classmethod - def from_grid(cls, grid): - return cls(PyFkTable(grid.raw)) - - @classmethod - def read(cls, path): - """Load an existing grid from file. - - Convenience wrapper for :meth:`pineappl.pineappl.PyFkTable.read()`. - - Parameters - ---------- - path : pathlike - file path - - Returns - ------- - FkTable - grid object - """ - return cls(PyFkTable.read(path)) - - def optimize(self, assumptions="Nf6Ind"): - """Optimize FK table storage. - - In order to perform any relevant optimization, assumptions are needed, and they are passed - as parameters to the function. - - Parameters - ---------- - assumptions : FkAssumptions or str - assumptions about the FkTable properties, declared by the user, deciding which - optimizations are possible - """ - if not isinstance(assumptions, FkAssumptions): - assumptions = FkAssumptions(assumptions) - return self._raw.optimize(assumptions._raw) - - -class FkAssumptions(PyWrapper): - """Python wrapper object to interface - :class:`~pineappl.pineappl.PyFkAssumptions`. - - Parameters - ---------- - assumption : str - assumption identifier - """ - - def __init__(self, assumption): - self._raw = PyFkAssumptions(assumption) diff --git a/pineappl_py/pineappl/grid.py b/pineappl_py/pineappl/grid.py deleted file mode 100644 index 2f962d949..000000000 --- a/pineappl_py/pineappl/grid.py +++ /dev/null @@ -1,392 +0,0 @@ -import numpy as np - -from .fk_table import FkTable -from .pineappl import PyGrid, PyOrder, PyOperatorSliceInfo, PyPidBasis -from .utils import PyWrapper - - -class Order(PyWrapper): - r"""Python wrapper object to interface :class:`~pineappl.pineappl.PyOrder`. - - Parameters - ---------- - alphas : int - power of :math:`\alpha_s` - alpha : int - power of :math:`\alpha` - logxir : int - power of :math:`\log(\xi_r)` - logxif : int - power of :math:`\log(\xi_f)` - """ - - def __init__(self, alphas, alpha, logxir, logxif): - self._raw = PyOrder(alphas, alpha, logxir, logxif) - - @staticmethod - def create_mask(orders, max_as, max_al, logs): - r""" - Return a mask suitable to pass as the `order_mask` parameter of - :meth:`Grid.convolve`. - - Parameters - ---------- - orders : list(Order) - list of available orders - max_as : int - maximum power of :math:`\alpha_s` - max_al : int - maximum power of :math:`\alpha` - logs : bool - whether to include log grids or not - - Returns - ------- - list(bool) - boolean mask - - """ - return PyOrder.create_mask([o._raw for o in orders], max_as, max_al, logs) - - -class Grid(PyWrapper): - r"""Python wrapper object to interface :class:`~pineappl.pineappl.PyGrid`. - - To create an object, you should call either :meth:`create` - or :meth:`read`. - - Parameters - ---------- - pygrid : PyGrid - raw wrapper object - """ - - def __init__(self, pygrid): - self._raw = pygrid - - @classmethod - def create(cls, lumi, orders, bin_limits, subgrid_params): - """Create a grid object from its ingredients. - - Parameters - --------- - lumi : list(LumiEntry) - List of active luminosities - orders: list(Order) - List of available orders - bin_limits: sequence(float) - Bin limits - subgrid_params : SubgridParams - subgrid parameters - """ - lumi = [lentry.raw for lentry in lumi] - orders = [o.raw for o in orders] - return cls(PyGrid(lumi, orders, np.array(bin_limits), subgrid_params.raw)) - - def subgrid(self, order, bin_, lumi): - """Retrieve the subgrid at the given position. - - Convenience wrapper for :meth:`pineappl.pineappl.PyGrid.set_subgrid()`. - - Parameters - ---------- - order : int - index of order - bin_ : int - index of bin - lumi : int - index of luminosity - - Returns - ------- - subgrid : Subgrid - subgrid content - """ - return self.raw.subgrid(order, bin_, lumi) - - def __getitem__(self, key): - """Retrieve the subgrid at the given position. - - Syntactic sugar for :meth:`subgrid` - - Parameters - ---------- - key : (int, int, int) - a 3-element integers tuple, consisting in `(order, bin, lumi)` - - Returns - ------- - subgrid : Subgrid - subgrid content - """ - if len(key) != 3: - raise ValueError("A tuple with `(order, bin, lumi)` is required as key.") - - return self.subgrid(*key) - - def set_subgrid(self, order, bin_, lumi, subgrid): - """Set the subgrid at the given position. - - Convenience wrapper for :meth:`pineappl.pineappl.PyGrid.set_subgrid()`. - - Parameters - ---------- - order : int - index of order - bin_ : int - index of bin - lumi : int - index of luminosity - subgrid : ImportOnlySubgridV1 - subgrid content - """ - self.raw.set_subgrid(order, bin_, lumi, subgrid.into()) - - def __setitem__(self, key, subgrid): - """Set the subgrid at the given position. - - Syntactic sugar for :meth:`set_subgrid` - - Parameters - ---------- - key : (int, int, int) - a 3-element integers tuple, consisting in `(order, bin, lumi)` - subgrid : ImportOnlySubgridV1 - subgrid content - """ - if len(key) != 3: - raise ValueError("A tuple with `(order, bin, lumi)` is required as key.") - - self.set_subgrid(*key, subgrid) - - def set_remapper(self, remapper): - """Set the normalizations. - - Convenience wrapper for :meth:`pineappl.pineappl.PyGrid.set_remapper()`. - - Parameters - ---------- - remapper: BinRemapper - Remapper object - """ - self.raw.set_remapper(remapper.raw) - - def orders(self): - """Extract the available perturbative orders and scale variations. - - Convenience wrapper for :meth:`pineappl.pineappl.PyGrid.orders()`. - - Parameters - ---------- - list(Order) : - list with perturbative orders and scale variations - """ - return [Order(*pyorder.as_tuple()) for pyorder in self.raw.orders()] - - def convolve_with_one( - self, - pdg_id, - xfx, - alphas, - order_mask=np.array([], dtype=bool), - bin_indices=np.array([], dtype=np.uint64), - lumi_mask=np.array([], dtype=bool), - xi=((1.0, 1.0),), - ): - r"""Convolute grid with pdf. - - Parameters - ---------- - pdg_id : int - PDG Monte Carlo ID of the hadronic particle `xfx` is the PDF for - xfx : callable - lhapdf like callable with arguments `pid, x, Q2` returning x*pdf for :math:`x`-grid - alphas : callable - lhapdf like callable with arguments `Q2` returning :math:`\alpha_s` - order_mask : sequence(bool) - Mask for selecting specific orders. The value `True` means the corresponding order - is included. An empty list corresponds to all orders being enabled. - bin_indices : sequence(int) - A list with the indices of the corresponding bins that should be calculated. An - empty list means that all orders should be calculated. - lumi_mask : sequence(bool) - Mask for selecting specific luminosity channels. The value `True` means the - corresponding channel is included. An empty list corresponds to all channels being - enabled. - xi : list((float, float)) - A list with the scale variation factors that should be used to calculate - scale-varied results. The first entry of a tuple corresponds to the variation of - the renormalization scale, the second entry to the variation of the factorization - scale. If only results for the central scale are need the list should contain - `(1.0, 1.0)`. - - Returns - ------- - list(float) : - cross sections for all bins, for each scale-variation tuple (first all bins, then - the scale variation) - """ - return self.raw.convolve_with_one( - pdg_id, - xfx, - alphas, - np.array(order_mask), - np.array(bin_indices), - np.array(lumi_mask), - xi, - ) - - def convolve_with_two( - self, - pdg_id1, - xfx1, - pdg_id2, - xfx2, - alphas, - order_mask=np.array([], dtype=bool), - bin_indices=np.array([], dtype=np.uint64), - lumi_mask=np.array([], dtype=bool), - xi=((1.0, 1.0),), - ): - r"""Convolute grid with two pdfs. - - Parameters - ---------- - pdg_id1 : int - PDG Monte Carlo ID of the hadronic particle `xfx1` is the PDF for - xfx1 : callable - lhapdf like callable with arguments `pid, x, Q2` returning x*pdf for :math:`x`-grid - pdg_id2 : int - PDG Monte Carlo ID of the hadronic particle `xfx2` is the PDF for - xfx2 : callable - lhapdf like callable with arguments `pid, x, Q2` returning x*pdf for :math:`x`-grid - alphas : callable - lhapdf like callable with arguments `Q2` returning :math:`\alpha_s` - order_mask : sequence(bool) - Mask for selecting specific orders. The value `True` means the corresponding order - is included. An empty list corresponds to all orders being enabled. - bin_indices : sequence(int) - A list with the indices of the corresponding bins that should be calculated. An - empty list means that all orders should be calculated. - lumi_mask : sequence(bool) - Mask for selecting specific luminosity channels. The value `True` means the - corresponding channel is included. An empty list corresponds to all channels being - enabled. - xi : list((float, float)) - A list with the scale variation factors that should be used to calculate - scale-varied results. The first entry of a tuple corresponds to the variation of - the renormalization scale, the second entry to the variation of the factorization - scale. If only results for the central scale are need the list should contain - `(1.0, 1.0)`. - - Returns - ------- - list(float) : - cross sections for all bins, for each scale-variation tuple (first all bins, then - the scale variation) - """ - return self.raw.convolve_with_two( - pdg_id1, - xfx1, - pdg_id2, - xfx2, - alphas, - np.array(order_mask), - np.array(bin_indices), - np.array(lumi_mask), - xi, - ) - - def evolve( - self, - operators, - mur2_grid, - alphas_values, - lumi_id_types="pdg_mc_ids", - order_mask=(), - xi=(1.0, 1.0), - ): - """Create an FKTable with the EKO. - - Convenience wrapper for :meth:`pineappl.pineappl.PyGrid.evolve()`. - - Parameters - ---------- - operators : dict - EKO Output - mur2_grid : list[float] - renormalization scales - alphas_values : list[float] - alpha_s values associated to the renormalization scales - lumi_id_types : str - kind of lumi types (e.g. "pdg_mc_ids" for flavor basis, "evol" - for evolution basis) - order_mask : list(bool) - Mask for selecting specific orders. The value `True` means the corresponding order - is included. An empty list corresponds to all orders being enabled. - xi : (float, float) - A tuple with the scale variation factors that should be used. - The first entry of a tuple corresponds to the variation of - the renormalization scale, the second entry to the variation of the factorization - scale. If only results for the central scale are need the tuple should be - `(1.0, 1.0)`. - - Returns - ------ - PyFkTable : - raw grid as an FKTable - """ - operator_grid = np.array( - [op["operators"] for op in operators["Q2grid"].values()] - ) - q2grid = list(operators["Q2grid"].keys()) - return FkTable( - self.raw.evolve( - np.array(operator_grid), - operators["q2_ref"], - np.array(operators["inputpids"], dtype=np.int32), - np.array(operators["inputgrid"]), - np.array(q2grid, dtype=np.float64), - np.array(operators["targetpids"], dtype=np.int32), - np.array(operators["targetgrid"]), - np.array(mur2_grid, dtype=np.float64), - np.array(alphas_values, dtype=np.float64), - xi, - lumi_id_types, - np.array(order_mask, dtype=bool), - ) - ) - - @classmethod - def read(cls, path): - """Load an existing grid from file. - - Convenience wrapper for :meth:`pineappl.pineappl.PyGrid.read()`. - - Parameters - ---------- - path : pathlike - file path - - Returns - ------- - Grid - grid object - """ - return cls(PyGrid.read(path)) - - def merge(self, other: "Grid"): - """Merge a second grid in the current one.""" - self.raw.merge(other.raw) - - def delete_bins(self, bin_indices): - """Delete bins. - - Repeated bins and those exceeding length are ignored. - - Parameters - ---------- - bin_indices : sequence(int) - list of indices of bins to removed - """ - self.raw.delete_bins(np.array(bin_indices, dtype=np.uint)) diff --git a/pineappl_py/pineappl/import_only_subgrid.py b/pineappl_py/pineappl/import_only_subgrid.py deleted file mode 100644 index 912015b05..000000000 --- a/pineappl_py/pineappl/import_only_subgrid.py +++ /dev/null @@ -1,48 +0,0 @@ -import numpy as np - -from .pineappl import PyImportOnlySubgridV1 -from .pineappl import PyImportOnlySubgridV2 -from .utils import PyWrapper - - -class ImportOnlySubgridV1(PyWrapper): - """ - Python wrapper object to :class:`~pineappl.pineappl.PyImportOnlySubgridV1`. - - Parameters - ---------- - array : numpy.ndarray(float, dim=3) - 3-dimensional subgrid content - q2_grid : sequence(float) - scale grid - x1_grid : sequence(float) - interpolation grid for :math:`x_1` - x2_grid : sequence(float) - interpolation grid for :math:`x_2` - """ - - def __init__(self, array, q2_grid, x1_grid, x2_grid): - self._raw = PyImportOnlySubgridV1( - np.array(array), np.array(q2_grid), np.array(x1_grid), np.array(x2_grid) - ) - -class ImportOnlySubgridV2(PyWrapper): - """ - Python wrapper object to :class:`~pineappl.pineappl.PyImportOnlySubgridV2`. - - Parameters - ---------- - array : numpy.ndarray(float, dim=3) - 3-dimensional subgrid content - mu2_grid : sequence(float) - scale grid - x1_grid : sequence(float) - interpolation grid for :math:`x_1` - x2_grid : sequence(float) - interpolation grid for :math:`x_2` - """ - - def __init__(self, array, mu2_grid, x1_grid, x2_grid): - self._raw = PyImportOnlySubgridV2( - np.array(array), mu2_grid, np.array(x1_grid), np.array(x2_grid) - ) diff --git a/pineappl_py/pineappl/lumi.py b/pineappl_py/pineappl/lumi.py deleted file mode 100644 index ff0ad2809..000000000 --- a/pineappl_py/pineappl/lumi.py +++ /dev/null @@ -1,16 +0,0 @@ -from .pineappl import PyLumiEntry -from .utils import PyWrapper - - -class LumiEntry(PyWrapper): - """ - Python wrapper object to :class:`~pineappl.pineappl.PyLumiEntry`. - - Parameters - ---------- - lumis : list(tuple(int,int,float)) - sequence describing a luminosity function. - """ - - def __init__(self, lumis): - self._raw = PyLumiEntry(lumis) diff --git a/pineappl_py/pineappl/subgrid.py b/pineappl_py/pineappl/subgrid.py deleted file mode 100644 index 00a5b25de..000000000 --- a/pineappl_py/pineappl/subgrid.py +++ /dev/null @@ -1,16 +0,0 @@ -from .pineappl import PySubgridParams, PyMu2 -from .utils import PyWrapper - - -class SubgridParams(PyWrapper): - """ - Python wrapper object to :class:`~pineappl.pineappl.PySubgridParams`. - """ - - def __init__(self): - self._raw = PySubgridParams() - -class Mu2(PyWrapper): - - def __init__(self, ren, fac): - self._raw = PyMu2(ren, fac) diff --git a/pineappl_py/pineappl/utils.py b/pineappl_py/pineappl/utils.py deleted file mode 100644 index bc9a984f3..000000000 --- a/pineappl_py/pineappl/utils.py +++ /dev/null @@ -1,19 +0,0 @@ -class PyWrapper: - """ - Python wrapper helper to delegate function calls to the underlying - raw object. - """ - - _raw = None - - @property - def raw(self): - """Raw PyO3 object""" - return self._raw - - def __getattr__(self, name): - """Delegate function calls down.""" - if name[0] != "_": - return self._raw.__getattribute__(name) - else: - raise AttributeError From 7f981447cb52a8a543b128eeb46ad02435cdc3c3 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Tue, 6 Aug 2024 11:40:22 +0200 Subject: [PATCH 02/51] add custom names to structs --- pineappl_py/src/bin.rs | 2 +- pineappl_py/src/fk_table.rs | 4 ++-- pineappl_py/src/grid.rs | 8 ++++---- pineappl_py/src/import_only_subgrid.rs | 4 ++-- pineappl_py/src/lumi.rs | 2 +- pineappl_py/src/subgrid.rs | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pineappl_py/src/bin.rs b/pineappl_py/src/bin.rs index f23038b66..82aa7d945 100644 --- a/pineappl_py/src/bin.rs +++ b/pineappl_py/src/bin.rs @@ -6,7 +6,7 @@ use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::bin::BinRemapper ` /// /// **Usage**: `yadism` -#[pyclass] +#[pyclass(name = "BinRemapper")] #[derive(Clone)] #[repr(transparent)] pub struct PyBinRemapper { diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index ec43717e1..e488f648c 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -16,13 +16,13 @@ use crate::grid::PyGrid; /// PyO3 wrapper to :rustdoc:`pineappl::fk_table::FkTable ` /// /// *Usage*: `pineko`, `yadism` -#[pyclass] +#[pyclass(name = "FkTable")] #[repr(transparent)] pub struct PyFkTable { pub(crate) fk_table: FkTable, } -#[pyclass] +#[pyclass(name = "FkAssumptions")] #[repr(transparent)] pub struct PyFkAssumptions { pub(crate) fk_assumptions: FkAssumptions, diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index f89c22da2..3640b5a97 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -28,7 +28,7 @@ use pyo3::types::PyIterator; /// PyO3 wrapper to :rustdoc:`pineappl::grid::Order ` /// /// **Usage**: `yadism` -#[pyclass] +#[pyclass(name = "Order")] #[repr(transparent)] pub struct PyOrder { pub(crate) order: Order, @@ -36,7 +36,7 @@ pub struct PyOrder { // TODO: should probably be in a different module // TODO: rename to `PidBasis` -#[pyclass] +#[pyclass(name = "PidBasis")] #[derive(Clone)] pub enum PyPidBasis { Pdg, @@ -54,7 +54,7 @@ impl From for PidBasis { // TODO: should probably be in a different module // TODO: rename to `OperatorSliceInfo` -#[pyclass] +#[pyclass(name = "OperatorSliceInfo")] #[derive(Clone)] pub struct PyOperatorSliceInfo { info: OperatorSliceInfo, @@ -152,7 +152,7 @@ impl PyOrder { /// PyO3 wrapper to :rustdoc:`pineappl::grid::Grid ` /// /// **Usage**: `yadism`, `pineko`, FKTable interface -#[pyclass] +#[pyclass(name = "Grid")] #[repr(transparent)] #[derive(Clone)] pub struct PyGrid { diff --git a/pineappl_py/src/import_only_subgrid.rs b/pineappl_py/src/import_only_subgrid.rs index 473333798..5758fcf73 100644 --- a/pineappl_py/src/import_only_subgrid.rs +++ b/pineappl_py/src/import_only_subgrid.rs @@ -10,7 +10,7 @@ use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::import_only_subgrid::ImportOnlySubgridV2 ` /// /// **Usage**: `pineko` -#[pyclass] +#[pyclass(name = "ImportOnlySubgridV2")] #[derive(Clone)] #[repr(transparent)] pub struct PyImportOnlySubgridV2 { @@ -71,7 +71,7 @@ impl PyImportOnlySubgridV2 { /// PyO3 wrapper to :rustdoc:`pineappl::import_only_subgrid::ImportOnlySubgridV1 ` /// /// **Usage**: `yadism` -#[pyclass] +#[pyclass(name = "ImportOnlySubgridV1")] #[derive(Clone)] #[repr(transparent)] pub struct PyImportOnlySubgridV1 { diff --git a/pineappl_py/src/lumi.rs b/pineappl_py/src/lumi.rs index cb0d4e736..7328fa8ab 100644 --- a/pineappl_py/src/lumi.rs +++ b/pineappl_py/src/lumi.rs @@ -11,7 +11,7 @@ use pyo3::prelude::*; /// 1. the PDG id of the first incoming parton /// 2. the PDG id of the second parton /// 3. a numerical factor that will multiply the result for this specific combination. -#[pyclass] +#[pyclass(name = "LumiEntry")] #[repr(transparent)] pub struct PyLumiEntry { pub(crate) lumi_entry: Channel, diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index e9085c967..076f44543 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -7,7 +7,7 @@ use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::subgrid::SubgridParams ` /// /// **Usage**: `yadism` -#[pyclass] +#[pyclass(name = "SubgridParams")] #[repr(transparent)] pub struct PySubgridParams { pub(crate) subgrid_params: SubgridParams, @@ -146,7 +146,7 @@ impl PySubgridParams { } /// PyO3 wrapper to :rustdoc:`pineappl::subgrid::Mu2 ` -#[pyclass] +#[pyclass(name = "Mu2")] #[repr(transparent)] pub struct PyMu2 { pub mu2: Mu2, @@ -185,7 +185,7 @@ impl PyMu2 { } /// PyO3 wrapper to :rustdoc:`pineappl::subgrid::SubgridEnum ` -#[pyclass] +#[pyclass(name = "SubgridEnum")] #[derive(Clone)] #[repr(transparent)] pub struct PySubgridEnum { From 5aa3772da7e96d2bcd3b907c7826ade8c5f27222 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Wed, 7 Aug 2024 15:43:37 +0200 Subject: [PATCH 03/51] [working py interface] probably to be reverted --- pineappl_py/src/grid.rs | 26 ++++++++++--------- pineappl_py/tests/test_bin.py | 5 ++-- pineappl_py/tests/test_fk_table.py | 18 +++++++------- pineappl_py/tests/test_grid.py | 40 ++++++++++++++---------------- pineappl_py/tests/test_lumi.py | 5 ++-- pineappl_py/tests/test_sugrid.py | 39 +++++++++++++++-------------- 6 files changed, 66 insertions(+), 67 deletions(-) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 3640b5a97..50f567536 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -383,15 +383,16 @@ impl PyGrid { /// numpy.ndarray(float) : /// cross sections for all bins, for each scale-variation tuple (first all bins, then /// the scale variation) + #[pyo3(signature = (pdg_id, xfx, alphas, order_mask = None, bin_indices = None, lumi_mask= None, xi = None))] pub fn convolve_with_one<'py>( &self, pdg_id: i32, xfx: &Bound<'py, PyAny>, alphas: &Bound<'py, PyAny>, - order_mask: PyReadonlyArray1, - bin_indices: PyReadonlyArray1, - lumi_mask: PyReadonlyArray1, - xi: Vec<(f64, f64)>, + order_mask: Option>, + bin_indices: Option>, + lumi_mask: Option>, + xi: Option>, py: Python<'py>, ) -> Bound<'py, PyArray1> { let mut xfx = |id, x, q2| xfx.call1((id, x, q2)).unwrap().extract().unwrap(); @@ -401,10 +402,10 @@ impl PyGrid { self.grid .convolve( &mut lumi_cache, - &order_mask.to_vec().unwrap(), - &bin_indices.to_vec().unwrap(), - &lumi_mask.to_vec().unwrap(), - &xi, + &order_mask.map_or(vec![], |b| b.to_vec().unwrap()), + &bin_indices.map_or(vec![], |c| c.to_vec().unwrap()), + &lumi_mask.map_or(vec![], |d| d.to_vec().unwrap()), + &xi.map_or(vec![(1.0, 1.0)], |m| m), ) .into_pyarray_bound(py) } @@ -447,6 +448,7 @@ impl PyGrid { /// numpy.ndarray(float) : /// cross sections for all bins, for each scale-variation tuple (first all bins, then /// the scale variation) + #[pyo3(signature = (pdg_id1, xfx1, pdg_id2, xfx2, alphas, order_mask = None, bin_indices = None, lumi_mask= None, xi = None))] pub fn convolve_with_two<'py>( &self, pdg_id1: i32, @@ -469,10 +471,10 @@ impl PyGrid { self.grid .convolve( &mut lumi_cache, - &order_mask.to_vec().unwrap(), - &bin_indices.to_vec().unwrap(), - &lumi_mask.to_vec().unwrap(), - &xi, + &order_mask.map_or(vec![], |b| b.to_vec().unwrap()), + &bin_indices.map_or(vec![], |c| c.to_vec().unwrap()), + &lumi_mask.map_or(vec![], |d| d.to_vec().unwrap()), + &xi.map_or(vec![(1.0, 1.0)], |m| m), ) .into_pyarray_bound(py) } diff --git a/pineappl_py/tests/test_bin.py b/pineappl_py/tests/test_bin.py index e8484a924..3feecd48a 100644 --- a/pineappl_py/tests/test_bin.py +++ b/pineappl_py/tests/test_bin.py @@ -5,10 +5,9 @@ class TestBinRemapper: def test_init(self): - br = pineappl.bin.BinRemapper(np.array([1.0]), [(2, 3)]) + br = pineappl.BinRemapper(np.array([1.0]), [(2, 3)]) - assert isinstance(br, pineappl.bin.BinRemapper) - assert isinstance(br.raw, pineappl.pineappl.PyBinRemapper) + assert isinstance(br, pineappl.BinRemapper) with pytest.raises(AttributeError): br._bla() diff --git a/pineappl_py/tests/test_fk_table.py b/pineappl_py/tests/test_fk_table.py index 4f9455e24..dcef8c5e4 100644 --- a/pineappl_py/tests/test_fk_table.py +++ b/pineappl_py/tests/test_fk_table.py @@ -5,11 +5,11 @@ class TestFkTable: def fake_grid(self, bins=None): - lumis = [pineappl.lumi.LumiEntry([(1, 21, 1.0)])] - orders = [pineappl.grid.Order(0, 0, 0, 0)] + lumis = [pineappl.LumiEntry([(1, 21, 1.0)])] + orders = [pineappl.Order(0, 0, 0, 0)] bin_limits = np.array([1e-7, 1e-3, 1] if bins is None else bins, dtype=float) - subgrid_params = pineappl.subgrid.SubgridParams() - g = pineappl.grid.Grid.create(lumis, orders, bin_limits, subgrid_params) + subgrid_params = pineappl.SubgridParams() + g = pineappl.Grid(lumis, orders, bin_limits, subgrid_params) return g def test_convolve_with_one(self): @@ -18,14 +18,14 @@ def test_convolve_with_one(self): # DIS grid xs = np.linspace(0.5, 1.0, 5) vs = xs.copy() - subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( + subgrid = pineappl.ImportOnlySubgridV1( vs[np.newaxis, :, np.newaxis], np.array([90.0]), xs, np.array([1.0]), ) - g.set_subgrid(0, 0, 0, subgrid) - fk = pineappl.fk_table.FkTable.from_grid(g) + g.set_subgrid(0, 0, 0, subgrid.into()) + fk = pineappl.FkTable(g) np.testing.assert_allclose( fk.convolve_with_one(2212, lambda pid, x, q2: 0.0), [0.0] * 2, @@ -35,8 +35,8 @@ def test_convolve_with_one(self): [5e7 / 9999, 0.0], ) - info = pineappl.grid.PyOperatorSliceInfo( - 1.0, [], [], 1.0, [], [], pineappl.grid.PyPidBasis.Pdg + info = pineappl.OperatorSliceInfo( + 1.0, [], [], 1.0, [], [], pineappl.PidBasis.Pdg ) # TODO: write a better test diff --git a/pineappl_py/tests/test_grid.py b/pineappl_py/tests/test_grid.py index 83ad810a1..38d37f3d8 100644 --- a/pineappl_py/tests/test_grid.py +++ b/pineappl_py/tests/test_grid.py @@ -7,26 +7,24 @@ class TestOrder: def test_init(self): args = (2, 1, 0, 1) - o = pineappl.grid.Order(*args) + o = pineappl.Order(*args) - assert isinstance(o, pineappl.grid.Order) - assert isinstance(o.raw, pineappl.pineappl.PyOrder) + assert isinstance(o, pineappl.Order) assert o.as_tuple() == args class TestGrid: def fake_grid(self, bins=None): - lumis = [pineappl.lumi.LumiEntry([(1, 21, 0.1)])] - orders = [pineappl.grid.Order(3, 0, 0, 0)] + lumis = [pineappl.LumiEntry([(1, 21, 0.1)])] + orders = [pineappl.Order(3, 0, 0, 0)] bin_limits = np.array([1e-7, 1e-3, 1] if bins is None else bins, dtype=float) - subgrid_params = pineappl.subgrid.SubgridParams() - g = pineappl.grid.Grid.create(lumis, orders, bin_limits, subgrid_params) + subgrid_params = pineappl.SubgridParams() + g = pineappl.Grid(lumis, orders, bin_limits, subgrid_params) return g def test_init(self): g = self.fake_grid() - assert isinstance(g, pineappl.grid.Grid) - assert isinstance(g.raw, pineappl.pineappl.PyGrid) + assert isinstance(g, pineappl.Grid) # orders assert len(g.orders()) == 1 assert g.orders()[0].as_tuple() == (3, 0, 0, 0) @@ -37,22 +35,22 @@ def test_set_subgrid(self): # DIS grid xs = np.linspace(0.1, 1.0, 5) vs = np.random.rand(len(xs)) - subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( + subgrid = pineappl.ImportOnlySubgridV1( vs[np.newaxis, :, np.newaxis], np.array([90.0]), np.array(xs), np.array([1.0]), ) - g.set_subgrid(0, 0, 0, subgrid) + g.set_subgrid(0, 0, 0, subgrid.into()) # let's mix it for fun with an hadronic one x1s = np.linspace(0.1, 1, 2) x2s = np.linspace(0.5, 1, 2) Q2s = np.linspace(10, 20, 2) - subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( + subgrid = pineappl.ImportOnlySubgridV1( np.random.rand(len(Q2s), len(x1s), len(x2s)), Q2s, x1s, x2s ) - g.set_subgrid(0, 1, 0, subgrid) + g.set_subgrid(0, 1, 0, subgrid.into()) g.optimize() def test_set_key_value(self): @@ -64,16 +62,16 @@ def test_set_key_value(self): def test_bins(self): g = self.fake_grid() # 1D - normalizations = [1.0] * 2 + normalizations = np.array([1.0, 1.0]) limits = [(1, 1), (2, 2)] - remapper = pineappl.bin.BinRemapper(normalizations, limits) + remapper = pineappl.BinRemapper(normalizations, limits) g.set_remapper(remapper) assert g.bin_dimensions() == 1 np.testing.assert_allclose(g.bin_left(0), [1, 2]) np.testing.assert_allclose(g.bin_right(0), [1, 2]) # 2D limits = [(1, 2), (2, 3), (2, 4), (3, 5)] - remapper = pineappl.bin.BinRemapper(normalizations, limits) + remapper = pineappl.BinRemapper(normalizations, limits) g.set_remapper(remapper) assert g.bin_dimensions() == 2 np.testing.assert_allclose(g.bin_left(0), [1, 2]) @@ -87,13 +85,13 @@ def test_convolve_with_one(self): # DIS grid xs = np.linspace(0.5, 1.0, 5) vs = xs.copy() - subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( + subgrid = pineappl.ImportOnlySubgridV1( vs[np.newaxis, :, np.newaxis], np.array([90.0]), xs, np.array([1.0]), ) - g.set_subgrid(0, 0, 0, subgrid) + g.set_subgrid(0, 0, 0, subgrid.into()) np.testing.assert_allclose( g.convolve_with_one(2212, lambda pid, x, q2: 0.0, lambda q2: 0.0), [0.0] * 2, @@ -112,9 +110,9 @@ def test_io(self, tmp_path): p = tmp_path / "test.pineappl" p.write_text("") g.write(str(p)) - gg = pineappl.grid.Grid.read(p) - assert isinstance(gg, pineappl.grid.Grid) - _ = pineappl.grid.Grid.read(str(p)) + gg = pineappl.Grid.read(p) + assert isinstance(gg, pineappl.Grid) + _ = pineappl.Grid.read(str(p)) def test_fill(self): g = self.fake_grid() diff --git a/pineappl_py/tests/test_lumi.py b/pineappl_py/tests/test_lumi.py index 2e466227f..763f8d0a9 100644 --- a/pineappl_py/tests/test_lumi.py +++ b/pineappl_py/tests/test_lumi.py @@ -3,7 +3,6 @@ class TestLumiEntry: def test_init(self): - le = pineappl.lumi.LumiEntry([(2, 2, 0.5)]) + le = pineappl.LumiEntry([(2, 2, 0.5)]) - assert isinstance(le, pineappl.lumi.LumiEntry) - assert isinstance(le.raw, pineappl.pineappl.PyLumiEntry) + assert isinstance(le, pineappl.LumiEntry) diff --git a/pineappl_py/tests/test_sugrid.py b/pineappl_py/tests/test_sugrid.py index d5b7aeb5b..114693219 100644 --- a/pineappl_py/tests/test_sugrid.py +++ b/pineappl_py/tests/test_sugrid.py @@ -6,19 +6,18 @@ class TestSubgridParams: def test_init(self): - sp = pineappl.subgrid.SubgridParams() - - assert isinstance(sp, pineappl.subgrid.SubgridParams) - assert isinstance(sp.raw, pineappl.pineappl.PySubgridParams) + sp = pineappl.SubgridParams() + assert isinstance(sp, pineappl.SubgridParams) def test_issue_164(pdf): - luminosities = [pineappl.lumi.LumiEntry([(1, 2, 1.0)])] - orders = [pineappl.grid.Order(0, 0, 0, 0)] - params = pineappl.subgrid.SubgridParams() + luminosities = [pineappl.LumiEntry([(1, 2, 1.0)])] + orders = [pineappl.Order(0, 0, 0, 0)] + params = pineappl.SubgridParams() def convolve_grid(): - grid = pineappl.grid.Grid.create(luminosities, orders, [0.0, 1.0], params) + bin_limits = np.array([0.0, 1.0]) + grid = pineappl.Grid(luminosities, orders, bin_limits, params) grid.fill(0.2, 0.2, 10, 0, 0.5, 0, 0.5) return grid.convolve_with_one(2212, pdf.xfxQ, pdf.alphasQ) @@ -31,42 +30,44 @@ def convolve_grid(): res = convolve_grid() assert pytest.approx(res) != 0.0 + class TestSubgrid: def fake_grid(self): - luminosities = [pineappl.lumi.LumiEntry([(1, 2, 1.0)])] - orders = [pineappl.grid.Order(0, 0, 0, 0)] - params = pineappl.subgrid.SubgridParams() - grid = pineappl.grid.Grid.create(luminosities, orders, [0.0, 1.0], params) + luminosities = [pineappl.LumiEntry([(1, 2, 1.0)])] + orders = [pineappl.Order(0, 0, 0, 0)] + params = pineappl.SubgridParams() + bin_limits = np.array([0.0, 1.0]) + grid = pineappl.Grid(luminosities, orders, bin_limits, params) return grid - + def fake_importonlysubgrid(self): x1s = np.linspace(0.1, 1, 2) x2s = np.linspace(0.5, 1, 2) Q2s = np.linspace(10, 20, 2) mu2s = [tuple([q2, q2]) for q2 in Q2s] array = np.random.rand(len(Q2s), len(x1s), len(x2s)) - subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV2(array, mu2s , x1s, x2s) + subgrid = pineappl.ImportOnlySubgridV2(array, mu2s, x1s, x2s) return subgrid, [x1s, x2s, mu2s, array] def test_subgrid_methods(self): grid = self.fake_grid() test_subgrid, infos = self.fake_importonlysubgrid() x1s, x2s, mu2s, _ = (obj for obj in infos) - grid.set_subgrid(0,0,0, test_subgrid) - extr_subgrid = grid.subgrid(0,0,0) + grid.set_subgrid(0, 0, 0, test_subgrid.into()) + extr_subgrid = grid.subgrid(0, 0, 0) facgrid = np.array([mu2.fac for mu2 in extr_subgrid.mu2_grid()]) rengrid = np.array([mu2.ren for mu2 in extr_subgrid.mu2_grid()]) np.testing.assert_allclose([mu2[0] for mu2 in mu2s], rengrid) np.testing.assert_allclose([mu2[1] for mu2 in mu2s], facgrid) np.testing.assert_allclose(extr_subgrid.x1_grid(), x1s) np.testing.assert_allclose(extr_subgrid.x2_grid(), x2s) - + def test_to_array3(self): grid = self.fake_grid() test_subgrid, infos = self.fake_importonlysubgrid() _, _, _, array = (obj for obj in infos) - grid.set_subgrid(0,0,0, test_subgrid) - extr_subgrid = grid.subgrid(0,0,0) + grid.set_subgrid(0, 0, 0, test_subgrid.into()) + extr_subgrid = grid.subgrid(0, 0, 0) test_array = extr_subgrid.to_array3() print(test_array) print(array) From 356f86f7e0eec0d98a9f4d96491017d91f3e55aa Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Wed, 7 Aug 2024 15:53:25 +0200 Subject: [PATCH 04/51] [working py interface] fixed missing Option --- pineappl_py/src/grid.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 50f567536..dfae4d79d 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -456,10 +456,10 @@ impl PyGrid { pdg_id2: i32, xfx2: &Bound<'py, PyAny>, alphas: &Bound<'py, PyAny>, - order_mask: PyReadonlyArray1, - bin_indices: PyReadonlyArray1, - lumi_mask: PyReadonlyArray1, - xi: Vec<(f64, f64)>, + order_mask: Option>, + bin_indices: Option>, + lumi_mask: Option>, + xi: Option>, py: Python<'py>, ) -> Bound<'py, PyArray1> { let mut xfx1 = |id, x, q2| xfx1.call1((id, x, q2)).unwrap().extract().unwrap(); From 0a148089a0af0a9d5eeb306bab6116a2567f18a0 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Wed, 7 Aug 2024 16:59:39 +0200 Subject: [PATCH 05/51] actually decide to have nested modules --- pineappl_py/src/bin.rs | 6 ++++++ pineappl_py/src/evolution.rs | 6 ++++++ pineappl_py/src/fk_table.rs | 7 ++++++ pineappl_py/src/grid.rs | 10 +++++++++ pineappl_py/src/import_only_subgrid.rs | 7 ++++++ pineappl_py/src/lib.rs | 22 +++++++------------ pineappl_py/src/lumi.rs | 6 ++++++ pineappl_py/src/subgrid.rs | 8 +++++++ pineappl_py/tests/test_bin.py | 4 ++-- pineappl_py/tests/test_fk_table.py | 16 +++++++------- pineappl_py/tests/test_grid.py | 30 +++++++++++++------------- pineappl_py/tests/test_lumi.py | 5 ++--- pineappl_py/tests/test_sugrid.py | 24 ++++++++++----------- 13 files changed, 97 insertions(+), 54 deletions(-) diff --git a/pineappl_py/src/bin.rs b/pineappl_py/src/bin.rs index 82aa7d945..d12faea7c 100644 --- a/pineappl_py/src/bin.rs +++ b/pineappl_py/src/bin.rs @@ -26,3 +26,9 @@ impl PyBinRemapper { Self::new(BinRemapper::new(normalizations.to_vec().unwrap(), limits).unwrap()) } } + +#[pymodule] +pub fn bin(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + Ok(()) +} diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index eb97e08eb..8698e9bbe 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -44,3 +44,9 @@ impl PyEvolveInfo { pub struct PyOperatorSliceInfo { pub(crate) slice_info: OperatorSliceInfo, } + +#[pymodule] +pub fn evolution(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + Ok(()) +} diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index e488f648c..12efa3eba 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -302,3 +302,10 @@ impl PyFkTable { self.fk_table.optimize(assumptions.fk_assumptions) } } + +#[pymodule] +pub fn fk_table(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + m.add_class::()?; + Ok(()) +} diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index dfae4d79d..2825119c4 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -869,3 +869,13 @@ impl PyGrid { self.grid.delete_bins(&bin_indices.to_vec().unwrap()) } } + +#[pymodule] +pub fn grid(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + + Ok(()) +} diff --git a/pineappl_py/src/import_only_subgrid.rs b/pineappl_py/src/import_only_subgrid.rs index 5758fcf73..a3e740412 100644 --- a/pineappl_py/src/import_only_subgrid.rs +++ b/pineappl_py/src/import_only_subgrid.rs @@ -129,3 +129,10 @@ impl PyImportOnlySubgridV1 { } } } + +#[pymodule] +pub fn import_only_subgrid(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + m.add_class::()?; + Ok(()) +} diff --git a/pineappl_py/src/lib.rs b/pineappl_py/src/lib.rs index 03b242887..5a20a07e2 100644 --- a/pineappl_py/src/lib.rs +++ b/pineappl_py/src/lib.rs @@ -2,6 +2,7 @@ #![allow(unsafe_op_in_unsafe_fn)] use pyo3::prelude::*; +use pyo3::wrap_pymodule; pub mod bin; pub mod evolution; @@ -16,20 +17,13 @@ pub mod subgrid; /// NOTE: this name has to match the one in Cargo.toml 'lib.name' #[pymodule] fn pineappl(m: &Bound<'_, PyModule>) -> PyResult<()> { - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; + m.add_wrapped(wrap_pymodule!(bin::bin))?; + m.add_wrapped(wrap_pymodule!(grid::grid))?; + m.add_wrapped(wrap_pymodule!(import_only_subgrid::import_only_subgrid))?; + m.add_wrapped(wrap_pymodule!(evolution::evolution))?; + m.add_wrapped(wrap_pymodule!(lumi::lumi))?; + m.add_wrapped(wrap_pymodule!(fk_table::fk_table))?; + m.add_wrapped(wrap_pymodule!(subgrid::subgrid))?; m.add("version", env!("CARGO_PKG_VERSION"))?; Ok(()) diff --git a/pineappl_py/src/lumi.rs b/pineappl_py/src/lumi.rs index 7328fa8ab..63c49bda3 100644 --- a/pineappl_py/src/lumi.rs +++ b/pineappl_py/src/lumi.rs @@ -42,3 +42,9 @@ impl PyLumiEntry { self.lumi_entry.entry().to_vec() } } + +#[pymodule] +pub fn lumi(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + Ok(()) +} diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index 076f44543..2717bf398 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -230,3 +230,11 @@ impl PySubgridEnum { PyArray1::from_slice_bound(py, &self.subgrid_enum.x2_grid()) } } + +#[pymodule] +pub fn subgrid(_py: Python, m: &PyModule) -> PyResult<()> { + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + Ok(()) +} diff --git a/pineappl_py/tests/test_bin.py b/pineappl_py/tests/test_bin.py index 3feecd48a..66044c782 100644 --- a/pineappl_py/tests/test_bin.py +++ b/pineappl_py/tests/test_bin.py @@ -5,9 +5,9 @@ class TestBinRemapper: def test_init(self): - br = pineappl.BinRemapper(np.array([1.0]), [(2, 3)]) + br = pineappl.bin.BinRemapper(np.array([1.0]), [(2, 3)]) - assert isinstance(br, pineappl.BinRemapper) + assert isinstance(br, pineappl.bin.BinRemapper) with pytest.raises(AttributeError): br._bla() diff --git a/pineappl_py/tests/test_fk_table.py b/pineappl_py/tests/test_fk_table.py index dcef8c5e4..b8ac400c0 100644 --- a/pineappl_py/tests/test_fk_table.py +++ b/pineappl_py/tests/test_fk_table.py @@ -5,11 +5,11 @@ class TestFkTable: def fake_grid(self, bins=None): - lumis = [pineappl.LumiEntry([(1, 21, 1.0)])] - orders = [pineappl.Order(0, 0, 0, 0)] + lumis = [pineappl.lumi.LumiEntry([(1, 21, 1.0)])] + orders = [pineappl.grid.Order(0, 0, 0, 0)] bin_limits = np.array([1e-7, 1e-3, 1] if bins is None else bins, dtype=float) - subgrid_params = pineappl.SubgridParams() - g = pineappl.Grid(lumis, orders, bin_limits, subgrid_params) + subgrid_params = pineappl.subgrid.SubgridParams() + g = pineappl.grid.Grid(lumis, orders, bin_limits, subgrid_params) return g def test_convolve_with_one(self): @@ -18,14 +18,14 @@ def test_convolve_with_one(self): # DIS grid xs = np.linspace(0.5, 1.0, 5) vs = xs.copy() - subgrid = pineappl.ImportOnlySubgridV1( + subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( vs[np.newaxis, :, np.newaxis], np.array([90.0]), xs, np.array([1.0]), ) g.set_subgrid(0, 0, 0, subgrid.into()) - fk = pineappl.FkTable(g) + fk = pineappl.fk_table.FkTable(g) np.testing.assert_allclose( fk.convolve_with_one(2212, lambda pid, x, q2: 0.0), [0.0] * 2, @@ -35,8 +35,8 @@ def test_convolve_with_one(self): [5e7 / 9999, 0.0], ) - info = pineappl.OperatorSliceInfo( - 1.0, [], [], 1.0, [], [], pineappl.PidBasis.Pdg + info = pineappl.grid.OperatorSliceInfo( + 1.0, [], [], 1.0, [], [], pineappl.grid.PidBasis.Pdg ) # TODO: write a better test diff --git a/pineappl_py/tests/test_grid.py b/pineappl_py/tests/test_grid.py index 38d37f3d8..6aeedebb5 100644 --- a/pineappl_py/tests/test_grid.py +++ b/pineappl_py/tests/test_grid.py @@ -7,24 +7,24 @@ class TestOrder: def test_init(self): args = (2, 1, 0, 1) - o = pineappl.Order(*args) + o = pineappl.grid.Order(*args) - assert isinstance(o, pineappl.Order) + assert isinstance(o, pineappl.grid.Order) assert o.as_tuple() == args class TestGrid: def fake_grid(self, bins=None): - lumis = [pineappl.LumiEntry([(1, 21, 0.1)])] - orders = [pineappl.Order(3, 0, 0, 0)] + lumis = [pineappl.lumi.LumiEntry([(1, 21, 0.1)])] + orders = [pineappl.grid.Order(3, 0, 0, 0)] bin_limits = np.array([1e-7, 1e-3, 1] if bins is None else bins, dtype=float) - subgrid_params = pineappl.SubgridParams() - g = pineappl.Grid(lumis, orders, bin_limits, subgrid_params) + subgrid_params = pineappl.subgrid.SubgridParams() + g = pineappl.grid.Grid(lumis, orders, bin_limits, subgrid_params) return g def test_init(self): g = self.fake_grid() - assert isinstance(g, pineappl.Grid) + assert isinstance(g, pineappl.grid.Grid) # orders assert len(g.orders()) == 1 assert g.orders()[0].as_tuple() == (3, 0, 0, 0) @@ -35,7 +35,7 @@ def test_set_subgrid(self): # DIS grid xs = np.linspace(0.1, 1.0, 5) vs = np.random.rand(len(xs)) - subgrid = pineappl.ImportOnlySubgridV1( + subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( vs[np.newaxis, :, np.newaxis], np.array([90.0]), np.array(xs), @@ -47,7 +47,7 @@ def test_set_subgrid(self): x1s = np.linspace(0.1, 1, 2) x2s = np.linspace(0.5, 1, 2) Q2s = np.linspace(10, 20, 2) - subgrid = pineappl.ImportOnlySubgridV1( + subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( np.random.rand(len(Q2s), len(x1s), len(x2s)), Q2s, x1s, x2s ) g.set_subgrid(0, 1, 0, subgrid.into()) @@ -64,14 +64,14 @@ def test_bins(self): # 1D normalizations = np.array([1.0, 1.0]) limits = [(1, 1), (2, 2)] - remapper = pineappl.BinRemapper(normalizations, limits) + remapper = pineappl.bin.BinRemapper(normalizations, limits) g.set_remapper(remapper) assert g.bin_dimensions() == 1 np.testing.assert_allclose(g.bin_left(0), [1, 2]) np.testing.assert_allclose(g.bin_right(0), [1, 2]) # 2D limits = [(1, 2), (2, 3), (2, 4), (3, 5)] - remapper = pineappl.BinRemapper(normalizations, limits) + remapper = pineappl.bin.BinRemapper(normalizations, limits) g.set_remapper(remapper) assert g.bin_dimensions() == 2 np.testing.assert_allclose(g.bin_left(0), [1, 2]) @@ -85,7 +85,7 @@ def test_convolve_with_one(self): # DIS grid xs = np.linspace(0.5, 1.0, 5) vs = xs.copy() - subgrid = pineappl.ImportOnlySubgridV1( + subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV1( vs[np.newaxis, :, np.newaxis], np.array([90.0]), xs, @@ -110,9 +110,9 @@ def test_io(self, tmp_path): p = tmp_path / "test.pineappl" p.write_text("") g.write(str(p)) - gg = pineappl.Grid.read(p) - assert isinstance(gg, pineappl.Grid) - _ = pineappl.Grid.read(str(p)) + gg = pineappl.grid.Grid.read(p) + assert isinstance(gg, pineappl.grid.Grid) + _ = pineappl.grid.Grid.read(str(p)) def test_fill(self): g = self.fake_grid() diff --git a/pineappl_py/tests/test_lumi.py b/pineappl_py/tests/test_lumi.py index 763f8d0a9..d5c8ad353 100644 --- a/pineappl_py/tests/test_lumi.py +++ b/pineappl_py/tests/test_lumi.py @@ -3,6 +3,5 @@ class TestLumiEntry: def test_init(self): - le = pineappl.LumiEntry([(2, 2, 0.5)]) - - assert isinstance(le, pineappl.LumiEntry) + le = pineappl.lumi.LumiEntry([(2, 2, 0.5)]) + assert isinstance(le, pineappl.lumi.LumiEntry) diff --git a/pineappl_py/tests/test_sugrid.py b/pineappl_py/tests/test_sugrid.py index 114693219..66c78b833 100644 --- a/pineappl_py/tests/test_sugrid.py +++ b/pineappl_py/tests/test_sugrid.py @@ -6,18 +6,18 @@ class TestSubgridParams: def test_init(self): - sp = pineappl.SubgridParams() - assert isinstance(sp, pineappl.SubgridParams) + sp = pineappl.subgrid.SubgridParams() + assert isinstance(sp, pineappl.subgrid.SubgridParams) def test_issue_164(pdf): - luminosities = [pineappl.LumiEntry([(1, 2, 1.0)])] - orders = [pineappl.Order(0, 0, 0, 0)] - params = pineappl.SubgridParams() + luminosities = [pineappl.lumi.LumiEntry([(1, 2, 1.0)])] + orders = [pineappl.grid.Order(0, 0, 0, 0)] + params = pineappl.subgrid.SubgridParams() def convolve_grid(): bin_limits = np.array([0.0, 1.0]) - grid = pineappl.Grid(luminosities, orders, bin_limits, params) + grid = pineappl.grid.Grid(luminosities, orders, bin_limits, params) grid.fill(0.2, 0.2, 10, 0, 0.5, 0, 0.5) return grid.convolve_with_one(2212, pdf.xfxQ, pdf.alphasQ) @@ -33,11 +33,11 @@ def convolve_grid(): class TestSubgrid: def fake_grid(self): - luminosities = [pineappl.LumiEntry([(1, 2, 1.0)])] - orders = [pineappl.Order(0, 0, 0, 0)] - params = pineappl.SubgridParams() + luminosities = [pineappl.lumi.LumiEntry([(1, 2, 1.0)])] + orders = [pineappl.grid.Order(0, 0, 0, 0)] + params = pineappl.subgrid.SubgridParams() bin_limits = np.array([0.0, 1.0]) - grid = pineappl.Grid(luminosities, orders, bin_limits, params) + grid = pineappl.grid.Grid(luminosities, orders, bin_limits, params) return grid def fake_importonlysubgrid(self): @@ -46,7 +46,7 @@ def fake_importonlysubgrid(self): Q2s = np.linspace(10, 20, 2) mu2s = [tuple([q2, q2]) for q2 in Q2s] array = np.random.rand(len(Q2s), len(x1s), len(x2s)) - subgrid = pineappl.ImportOnlySubgridV2(array, mu2s, x1s, x2s) + subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV2(array, mu2s, x1s, x2s) return subgrid, [x1s, x2s, mu2s, array] def test_subgrid_methods(self): @@ -67,7 +67,7 @@ def test_to_array3(self): test_subgrid, infos = self.fake_importonlysubgrid() _, _, _, array = (obj for obj in infos) grid.set_subgrid(0, 0, 0, test_subgrid.into()) - extr_subgrid = grid.subgrid(0, 0, 0) + extr_subgrid = grid.subgrid(0,0,0) test_array = extr_subgrid.to_array3() print(test_array) print(array) From 3745f668ba4374b7044a1489b971d12a0b8bc7f8 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Thu, 8 Aug 2024 10:52:22 +0200 Subject: [PATCH 06/51] add spaces in signatures --- pineappl_py/src/grid.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 2825119c4..145d83ba3 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -383,7 +383,7 @@ impl PyGrid { /// numpy.ndarray(float) : /// cross sections for all bins, for each scale-variation tuple (first all bins, then /// the scale variation) - #[pyo3(signature = (pdg_id, xfx, alphas, order_mask = None, bin_indices = None, lumi_mask= None, xi = None))] + #[pyo3(signature = (pdg_id, xfx, alphas, order_mask = None, bin_indices = None, lumi_mask = None, xi = None))] pub fn convolve_with_one<'py>( &self, pdg_id: i32, @@ -448,7 +448,7 @@ impl PyGrid { /// numpy.ndarray(float) : /// cross sections for all bins, for each scale-variation tuple (first all bins, then /// the scale variation) - #[pyo3(signature = (pdg_id1, xfx1, pdg_id2, xfx2, alphas, order_mask = None, bin_indices = None, lumi_mask= None, xi = None))] + #[pyo3(signature = (pdg_id1, xfx1, pdg_id2, xfx2, alphas, order_mask = None, bin_indices = None, lumi_mask = None, xi = None))] pub fn convolve_with_two<'py>( &self, pdg_id1: i32, From aeddb822ea0fe125943d30f4bf3c9ee842ac860c Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Fri, 9 Aug 2024 09:54:16 +0200 Subject: [PATCH 07/51] various fixes in various places --- pineappl_py/src/channel.rs | 4 ++-- pineappl_py/src/grid.rs | 4 ++-- pineappl_py/tests/test_channel.py | 2 -- pineappl_py/tests/test_lumi.py | 4 ++-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pineappl_py/src/channel.rs b/pineappl_py/src/channel.rs index 4e46ab38f..5b2c4a42c 100644 --- a/pineappl_py/src/channel.rs +++ b/pineappl_py/src/channel.rs @@ -9,7 +9,7 @@ use pyo3::prelude::*; /// 1. the PDG id of the first incoming parton /// 2. the PDG id of the second parton /// 3. a numerical factor that will multiply the result for this specific combination. -#[pyclass(name = "LumiEntry")] +#[pyclass(name = "Channel")] #[repr(transparent)] pub struct PyChannel { pub(crate) entry: Channel, @@ -47,6 +47,6 @@ impl PyChannel { #[pymodule] pub fn channel(_py: Python, m: &PyModule) -> PyResult<()> { - m.add_class::()?; + m.add_class::()?; Ok(()) } diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index ea9fdb8e1..7783030e9 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -425,7 +425,7 @@ impl PyGrid { /// numpy.ndarray(float) : /// cross sections for all bins, for each scale-variation tuple (first all bins, then /// the scale variation) - #[pyo3(signature = (pdg_id, xfx, alphas, order_mask = None, bin_indices = None, lumi_mask = None, xi = None))] + #[pyo3(signature = (pdg_id, xfx, alphas, order_mask = None, bin_indices = None, channel_mask = None, xi = None))] pub fn convolve_with_one<'py>( &self, pdg_id: i32, @@ -488,7 +488,7 @@ impl PyGrid { /// numpy.ndarray(float) : /// cross sections for all bins, for each scale-variation tuple (first all bins, then /// the scale variation) - #[pyo3(signature = (pdg_id1, xfx1, pdg_id2, xfx2, alphas, order_mask = None, bin_indices = None, lumi_mask = None, xi = None))] + #[pyo3(signature = (pdg_id1, xfx1, pdg_id2, xfx2, alphas, order_mask = None, bin_indices = None, channel_mask = None, xi = None))] pub fn convolve_with_two<'py>( &self, pdg_id1: i32, diff --git a/pineappl_py/tests/test_channel.py b/pineappl_py/tests/test_channel.py index 16dce2e38..fd07df6b6 100644 --- a/pineappl_py/tests/test_channel.py +++ b/pineappl_py/tests/test_channel.py @@ -4,6 +4,4 @@ class TestChannel: def test_init(self): le = pineappl.channel.Channel([(2, 2, 0.5)]) - assert isinstance(le, pineappl.channel.Channel) - assert isinstance(le.raw, pineappl.pineappl.PyChannel) diff --git a/pineappl_py/tests/test_lumi.py b/pineappl_py/tests/test_lumi.py index d5c8ad353..7958fc362 100644 --- a/pineappl_py/tests/test_lumi.py +++ b/pineappl_py/tests/test_lumi.py @@ -3,5 +3,5 @@ class TestLumiEntry: def test_init(self): - le = pineappl.lumi.LumiEntry([(2, 2, 0.5)]) - assert isinstance(le, pineappl.lumi.LumiEntry) + le = pineappl.channel.Channel([(2, 2, 0.5)]) + assert isinstance(le, pineappl.channel.Channel) From 93d3c634d8df92d6e310bc79d7d75e9e711d7054 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Fri, 9 Aug 2024 13:40:33 +0200 Subject: [PATCH 08/51] remove lumi test and deprecated TODOs --- pineappl_py/src/grid.rs | 2 -- pineappl_py/tests/test_lumi.py | 7 ------- 2 files changed, 9 deletions(-) delete mode 100644 pineappl_py/tests/test_lumi.py diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 7783030e9..5ca059ab6 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -33,7 +33,6 @@ pub struct PyOrder { } // TODO: should probably be in a different module -// TODO: rename to `PidBasis` #[pyclass(name = "PidBasis")] #[derive(Clone)] pub enum PyPidBasis { @@ -51,7 +50,6 @@ impl From for PidBasis { } // TODO: should probably be in a different module -// TODO: rename to `OperatorSliceInfo` #[pyclass(name = "OperatorSliceInfo")] #[derive(Clone)] pub struct PyOperatorSliceInfo { diff --git a/pineappl_py/tests/test_lumi.py b/pineappl_py/tests/test_lumi.py deleted file mode 100644 index 7958fc362..000000000 --- a/pineappl_py/tests/test_lumi.py +++ /dev/null @@ -1,7 +0,0 @@ -import pineappl - - -class TestLumiEntry: - def test_init(self): - le = pineappl.channel.Channel([(2, 2, 0.5)]) - assert isinstance(le, pineappl.channel.Channel) From fc6d4667b36df601e850691b59b0569daa4d90b4 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Fri, 9 Aug 2024 16:02:02 +0200 Subject: [PATCH 09/51] move OperatorSliceInfo and PidBasis into evolution module --- pineappl_py/src/evolution.rs | 79 +++++++++++++++++++++++++++--- pineappl_py/src/grid.rs | 76 +--------------------------- pineappl_py/tests/test_fk_table.py | 4 +- 3 files changed, 75 insertions(+), 84 deletions(-) diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index 70f383113..fd7f3b90c 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -1,8 +1,77 @@ use numpy::{IntoPyArray, PyArray1}; use pineappl::evolution::{EvolveInfo, OperatorSliceInfo}; +use pineappl::pids::PidBasis; use pyo3::prelude::*; +/// PyO3 wrapper to :rustdoc:`pineappl::pids::PidBasis `. +#[pyclass(name = "PidBasis")] +#[derive(Clone)] +pub enum PyPidBasis { + Pdg, + Evol, +} + +impl From for PidBasis { + fn from(basis: PyPidBasis) -> Self { + match basis { + PyPidBasis::Pdg => Self::Pdg, + PyPidBasis::Evol => Self::Evol, + } + } +} + +/// PyO3 wrapper to :rustdoc:`pineappl::evolution::OperatorSliceInfo `. +#[pyclass(name = "OperatorSliceInfo")] +#[derive(Clone)] +pub struct PyOperatorSliceInfo { + pub(crate) info: OperatorSliceInfo, +} + +#[pymethods] +impl PyOperatorSliceInfo { + /// Constructor. + /// + /// Parameteters + /// ------------ + /// fac0 : float + /// initial factorization scale + /// pids0 : list(int) + /// flavors available at the initial scale + /// x0 : list(float) + /// x-grid at the initial scale + /// fac1 : float + /// evolved final scale + /// pids1 : list(int) + /// flavors available at the final scale + /// x1 : list(float) + /// x-grid at the final scale + /// pid_basis : PyPidBasis + /// flavor basis reprentation at the initial scale + #[new] + pub fn new( + fac0: f64, + pids0: Vec, + x0: Vec, + fac1: f64, + pids1: Vec, + x1: Vec, + pid_basis: PyPidBasis, + ) -> Self { + Self { + info: OperatorSliceInfo { + fac0, + pids0, + x0, + fac1, + pids1, + x1, + pid_basis: pid_basis.into(), + }, + } + } +} + /// PyO3 wrapper to :rustdoc:`pineappl::evolution::EvolveInfo `. #[pyclass] #[repr(transparent)] @@ -37,16 +106,10 @@ impl PyEvolveInfo { } } -/// PyO3 wrapper to :rustdoc:`pineappl::evolution::OperatorSliceInfo `. -#[pyclass] -#[repr(transparent)] -#[derive(Clone)] -pub struct PyOperatorSliceInfo { - pub(crate) slice_info: OperatorSliceInfo, -} - #[pymodule] pub fn evolution(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; + m.add_class::()?; + m.add_class::()?; Ok(()) } diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 5ca059ab6..e21dbbf3d 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -1,13 +1,12 @@ use ndarray::CowArray; use pineappl::boc::Order; use pineappl::convolutions::LumiCache; -use pineappl::evolution::{AlphasTable, OperatorInfo, OperatorSliceInfo}; +use pineappl::evolution::{AlphasTable, OperatorInfo}; use pineappl::grid::{Grid, Ntuple}; -use pineappl::pids::PidBasis; use super::bin::PyBinRemapper; use super::channel::PyChannel; -use super::evolution::PyEvolveInfo; +use super::evolution::{PyEvolveInfo, PyOperatorSliceInfo, PyPidBasis}; use super::fk_table::PyFkTable; use super::subgrid::{PySubgridEnum, PySubgridParams}; @@ -32,74 +31,6 @@ pub struct PyOrder { pub(crate) order: Order, } -// TODO: should probably be in a different module -#[pyclass(name = "PidBasis")] -#[derive(Clone)] -pub enum PyPidBasis { - Pdg, - Evol, -} - -impl From for PidBasis { - fn from(basis: PyPidBasis) -> Self { - match basis { - PyPidBasis::Pdg => Self::Pdg, - PyPidBasis::Evol => Self::Evol, - } - } -} - -// TODO: should probably be in a different module -#[pyclass(name = "OperatorSliceInfo")] -#[derive(Clone)] -pub struct PyOperatorSliceInfo { - info: OperatorSliceInfo, -} - -#[pymethods] -impl PyOperatorSliceInfo { - /// Constructor. - /// - /// Parameteters - /// ------------ - /// fac0 : float - /// initial factorization scale - /// pids0 : list(int) - /// flavors available at the initial scale - /// x0 : list(float) - /// x-grid at the initial scale - /// fac1 : float - /// evolved final scale - /// pids1 : list(int) - /// flavors available at the final scale - /// x1 : list(float) - /// x-grid at the final scale - /// pid_basis : PyPidBasis - /// flavor basis reprentation at the initial scale - #[new] - pub fn new( - fac0: f64, - pids0: Vec, - x0: Vec, - fac1: f64, - pids1: Vec, - x1: Vec, - pid_basis: PyPidBasis, - ) -> Self { - Self { - info: OperatorSliceInfo { - fac0, - pids0, - x0, - fac1, - pids1, - x1, - pid_basis: pid_basis.into(), - }, - } - } -} - impl PyOrder { pub(crate) fn new(order: Order) -> Self { Self { order } @@ -918,9 +849,6 @@ impl PyGrid { #[pymodule] pub fn grid(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; - m.add_class::()?; m.add_class::()?; - m.add_class::()?; - Ok(()) } diff --git a/pineappl_py/tests/test_fk_table.py b/pineappl_py/tests/test_fk_table.py index 3d16c1f2d..97237c745 100644 --- a/pineappl_py/tests/test_fk_table.py +++ b/pineappl_py/tests/test_fk_table.py @@ -35,8 +35,8 @@ def test_convolve_with_one(self): [5e7 / 9999, 0.0], ) - info = pineappl.grid.OperatorSliceInfo( - 1.0, [], [], 1.0, [], [], pineappl.grid.PidBasis.Pdg + info = pineappl.evolution.OperatorSliceInfo( + 1.0, [], [], 1.0, [], [], pineappl.evolution.PidBasis.Pdg ) # TODO: write a better test From 37c877ea63c4567dd451439faf4aebd394abb475 Mon Sep 17 00:00:00 2001 From: Tanjona Rabemananjara Date: Tue, 13 Aug 2024 08:25:58 +0200 Subject: [PATCH 10/51] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d4dbef1a..05fefa2f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - added new method `Grid::delete_orders` and the corresponding switch `--delete-orders` in the subcommand `write` of the CLI +### Changed + +- renamed `pineappl.lumi.rs` to `pineappl.channel.rs` +- removed `.create()` and `.from_grid()` methods and directly instantiate objecs from the class +- `.into()` needs to be explicitly called on subgrids when using `set_subgrid()` +- replaced `pineappl.grid.PidBasis` with `pineappl.evolution.PidBasis` +- replaced `pineappl.grid.OperatorSliceInfo` with `pineappl.evolution.OperatorSliceInfo` + ## [0.8.2] - 22/07/2024 ### Changed From 2bd81c0e4b8298ed6671a6972f5236c8caebfe71 Mon Sep 17 00:00:00 2001 From: Tanjona Rabemananjara Date: Tue, 13 Aug 2024 10:18:09 +0200 Subject: [PATCH 11/51] fixed update to CHANGELOG.md according to review --- CHANGELOG.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05fefa2f2..55c1ab6cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,11 +14,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- renamed `pineappl.lumi.rs` to `pineappl.channel.rs` -- removed `.create()` and `.from_grid()` methods and directly instantiate objecs from the class -- `.into()` needs to be explicitly called on subgrids when using `set_subgrid()` -- replaced `pineappl.grid.PidBasis` with `pineappl.evolution.PidBasis` -- replaced `pineappl.grid.OperatorSliceInfo` with `pineappl.evolution.OperatorSliceInfo` +- dropped top-level Python interface layer +- renamed `lumi` to `channel` in PyO3 Python interface. This concerns 1) the argument names of `convolute_with_one` and similar functions; 2) the module `Python API:pineappl.lumi` was moved to `Python API:pineappl.channel`; 3) the class `LumiEntry` was renamed to `Channel` +- `.into()` needs to be explicitly called on subgrids when calling `Python API:pineappl.grid.set_subgrid()` +- replaced `Python API:pineappl.grid.PyPidBasis` with `Python API:pineappl.evolution.PidBasis` +- replaced `Python API:pineappl.grid.PyOperatorSliceInfo` with `Python API:pineappl.evolution.OperatorSliceInfo` + +### Removed + +- removed `Python API:pineappl.grid.Grid.create()` and `Python API:pineappl.fk_table.FkTable.from_grid()` methods; use the constructors of the respective class instead ## [0.8.2] - 22/07/2024 From 230b188c48df1d817e7dbf949f74d271356de50f Mon Sep 17 00:00:00 2001 From: Tanjona Rabemananjara Date: Tue, 13 Aug 2024 11:15:29 +0200 Subject: [PATCH 12/51] fixed 'Python API' --- CHANGELOG.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55c1ab6cd..4d189eb43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,15 +14,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- dropped top-level Python interface layer -- renamed `lumi` to `channel` in PyO3 Python interface. This concerns 1) the argument names of `convolute_with_one` and similar functions; 2) the module `Python API:pineappl.lumi` was moved to `Python API:pineappl.channel`; 3) the class `LumiEntry` was renamed to `Channel` -- `.into()` needs to be explicitly called on subgrids when calling `Python API:pineappl.grid.set_subgrid()` -- replaced `Python API:pineappl.grid.PyPidBasis` with `Python API:pineappl.evolution.PidBasis` -- replaced `Python API:pineappl.grid.PyOperatorSliceInfo` with `Python API:pineappl.evolution.OperatorSliceInfo` +- Python API: dropped top-level Python interface layer +- Python API: renamed `lumi` to `channel` in PyO3 Python interface. + This concerns 1) the argument names of `convolute_with_one` and + similar functions; 2) the module `pineappl.lumi` was moved to + `pineappl.channel`; 3) the class `LumiEntry` was renamed to `Channel` +- Python API: `.into()` needs to be explicitly called on subgrids when + calling `pineappl.grid.set_subgrid()` +- Python API: replaced `pineappl.grid.PyPidBasis` with + `pineappl.evolution.PidBasis` +- Python API: replaced `pineappl.grid.PyOperatorSliceInfo` with + `pineappl.evolution.OperatorSliceInfo` ### Removed -- removed `Python API:pineappl.grid.Grid.create()` and `Python API:pineappl.fk_table.FkTable.from_grid()` methods; use the constructors of the respective class instead +- Python API: removed `pineappl.grid.Grid.create()` and + `pineappl.fk_table.FkTable.from_grid()` methods; use the constructors + of the respective class instead ## [0.8.2] - 22/07/2024 From 07cfb02308756b8b8806963ff1e09a7d3a317b25 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 10:56:51 +0200 Subject: [PATCH 13/51] Start fixing the documentation --- pineappl_py/docs/.gitignore | 1 - pineappl_py/docs/source/conf.py | 179 +++---------------- pineappl_py/docs/source/index.rst | 2 +- pineappl_py/docs/source/modules/pineappl.rst | 7 + 4 files changed, 35 insertions(+), 154 deletions(-) create mode 100644 pineappl_py/docs/source/modules/pineappl.rst diff --git a/pineappl_py/docs/.gitignore b/pineappl_py/docs/.gitignore index 3025cff24..1e6524a5f 100644 --- a/pineappl_py/docs/.gitignore +++ b/pineappl_py/docs/.gitignore @@ -1,7 +1,6 @@ # autogenerated file source/development/code_todos.rst # Ignore auto generated module references -source/modules source/development/ekomark # ignore temporary build files _build/ diff --git a/pineappl_py/docs/source/conf.py b/pineappl_py/docs/source/conf.py index 0026f9267..671aa7afb 100644 --- a/pineappl_py/docs/source/conf.py +++ b/pineappl_py/docs/source/conf.py @@ -1,84 +1,35 @@ # Configuration file for the Sphinx documentation builder. # -# This file only contains a selection of the most common options. For a full -# list see the documentation: +# For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -import pathlib -import os -import sys - -here = pathlib.Path(__file__).absolute().parent - # -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -project = "pineappl" -copyright = "2020-2021, the PineAPPL team" -author = "the PineAPPL team" +import pineappl +project = 'pineappl' +copyright = '2020–2024, the PineAPPL team' +author = 'the PineAPPL team' +release = pineappl.version +version = release -# -- General configuration --------------------------------------------------- -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.doctest", - "sphinx.ext.intersphinx", - "sphinx.ext.todo", - "sphinx.ext.coverage", - "sphinx.ext.mathjax", - "sphinx.ext.ifconfig", - "sphinx.ext.viewcode", - "sphinx.ext.autosectionlabel", - "sphinx.ext.napoleon", - "sphinxcontrib.bibtex", - "sphinx.ext.graphviz", - "sphinx.ext.extlinks", + 'sphinx.ext.autodoc', + 'sphinx.ext.autosectionlabel', + 'sphinx.ext.autosummary', + 'sphinx.ext.extlinks', + 'sphinx.ext.inheritance_diagram', + 'sphinx.ext.intersphinx', + 'sphinx.ext.napoleon', + 'sphinx.ext.todo', + 'sphinx_rtd_theme', + 'sphinxcontrib.bibtex', ] -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -source_suffix = { - ".rst": "restructuredtext", - ".txt": "restructuredtext", -} - -autosectionlabel_prefix_document = True -# autosectionlabel_maxdepth = 10 -# Allow to embed rst syntax in markdown files. -enable_eval_rst = True - -# The master toctree document. -master_doc = "index" -bibtex_bibfiles = ["refs.bib"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["shared/*"] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = None - -# A string to be included at the beginning of all files -shared = here / "shared" -rst_prolog = "\n".join([open(x).read() for x in os.scandir(shared)]) +autosummary_generate = True +autosummary_imported_members = True extlinks = { "yadism": ("https://nnpdf.github.io/yadism/%s", "yadism - %s"), @@ -86,89 +37,13 @@ "pineko": ("https://github.com/NNPDF/pineko/%s", "pineko - %s"), } -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# -- Extension configuration ------------------------------------------------- - -# -- Options for intersphinx extension --------------------------------------- - -# Example configuration for intersphinx: refer to the Python standard library. -# Thanks https://github.com/bskinn/sphobjinv -intersphinx_mapping = { - "python": ("https://docs.python.org/3/", None), - "scipy": ("https://docs.scipy.org/doc/scipy/", None), - "numpy": ("https://numpy.org/doc/stable", None), -} -# -- Options for todo extension ---------------------------------------------- - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - -mathjax3_config = { - "tex": { - "macros": { - # fncs - # "atan": [r"\text{atan}", 0], - # "span": [r"\text{span}", 0], - } - } -} - -# https://stackoverflow.com/questions/1871549/determine-if-python-is-running-inside-virtualenv -def get_base_prefix_compat(): - """Get base/real prefix, or sys.prefix if there is none.""" - return ( - getattr(sys, "base_prefix", None) - or getattr(sys, "real_prefix", None) - or sys.prefix - ) - - -def in_virtualenv(): - return get_base_prefix_compat() != sys.prefix - - -# https://github.com/readthedocs/readthedocs.org/issues/1139#issuecomment-312626491 -def run_apidoc(_): - import subprocess # pylint: disable=import-outside-toplevel - - from sphinx.ext.apidoc import main # pylint: disable=import-outside-toplevel - - sys.path.append(str(here.parent)) - # run maturin to have the latest stuff - pkg_root = here.parents[1] - # if in_virtualenv(): # in local repos we're always in a virtualenv - # subprocess.run(["maturin", "develop"], cwd=pkg_root) - # else: # on RTD we can't (for some reason we're not inside the virtualenv - or maybe only the subshell isn't) - # subprocess.run(["maturin", "build"], cwd=pkg_root) - # # On RTD we were already installing before, but of course this was fake - # # as it only had the raw Python stuff, so let's do it again - # subprocess.run(["pip", "uninstall", "pineappl", "-y"], cwd=pkg_root) - # wheels = list((pkg_root / "target" / "wheels").glob("pineappl*.whl")) - # # In case there are several wheels (as on RTD) find the one matching (and let the others happily fail) - # for wheel in wheels: - # subprocess.run(["pip", "install", str(wheel.absolute())], cwd=pkg_root) - - # analyse 'pineappl' - docs_dest = here / "modules" / "pineappl" - import pineappl +bibtex_bibfiles = ["refs.bib"] - # note that we can NOT point to the local directory (`here.parents[1] / "pineappl"`) - # but we need the package built by `maturin` and installed by `pip` - package = pathlib.Path(pineappl.__file__).parent - main(["--module-first", "-o", str(docs_dest), str(package)]) - (docs_dest / "modules.rst").unlink() +templates_path = ['_templates'] +exclude_patterns = [] +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -def setup(app): - app.connect("builder-inited", run_apidoc) +html_theme = 'sphinx_rtd_theme' +html_static_path = ['_static'] diff --git a/pineappl_py/docs/source/index.rst b/pineappl_py/docs/source/index.rst index 632e0addc..28160af76 100644 --- a/pineappl_py/docs/source/index.rst +++ b/pineappl_py/docs/source/index.rst @@ -18,7 +18,7 @@ The Python wrapper is also used in :yadism:`\ ` and :pineko:`\ `. We also list s installation recipes implementation - API + API indices .. important:: diff --git a/pineappl_py/docs/source/modules/pineappl.rst b/pineappl_py/docs/source/modules/pineappl.rst new file mode 100644 index 000000000..b66bc2097 --- /dev/null +++ b/pineappl_py/docs/source/modules/pineappl.rst @@ -0,0 +1,7 @@ +pineappl package +================ + +.. automodule:: pineappl + :members: + :undoc-members: + :show-inheritance: From c05e008670103fd8fd53deccec932ef8edc56c7f Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 10:57:26 +0200 Subject: [PATCH 14/51] Remove obsolete container files --- pineappl_py/package/Containerfile | 27 ---------- pineappl_py/package/README.md | 89 ------------------------------- pineappl_py/package/maturin | 8 --- 3 files changed, 124 deletions(-) delete mode 100644 pineappl_py/package/Containerfile delete mode 100644 pineappl_py/package/README.md delete mode 100755 pineappl_py/package/maturin diff --git a/pineappl_py/package/Containerfile b/pineappl_py/package/Containerfile deleted file mode 100644 index 49e5821a8..000000000 --- a/pineappl_py/package/Containerfile +++ /dev/null @@ -1,27 +0,0 @@ -FROM quay.io/pypa/manylinux2014_x86_64 - -ARG MATURIN_TAR='maturin-x86_64-unknown-linux-musl.tar.gz' -ARG MATURIN_TAG='v0.13.0-beta.9' - -# install c compiler -# and create a dedicated user -RUN /bin/bash -c "yum install gcc -y; \ - useradd -m pineappl;\ - su - pineappl" - -USER pineappl - -# install dependencies -# - rust -# - maturin -RUN /bin/bash -c "cd ${HOME}; \ - mkdir -p local/bin; \ - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \ - curl --remote-name -L https://github.com/PyO3/maturin/releases/download/${MATURIN_TAG}/${MATURIN_TAR}; \ - tar -xvzf ${MATURIN_TAR} --directory=local/bin/" - -COPY maturin /home/pineappl - -ENTRYPOINT ["/home/pineappl/maturin"] -# To minimize the size of the wheel use '--strip' -CMD ["build --release --interpreter 3.7 3.8 3.9 3.10 pypy3.7"] diff --git a/pineappl_py/package/README.md b/pineappl_py/package/README.md deleted file mode 100644 index 69defc670..000000000 --- a/pineappl_py/package/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# Packaging python interface - -In order to compile wheels to distribute some requirements have to be met: - -- `linux`: the compilation process has to be run in a - [`manylinux`](https://github.com/pypa/manylinux) compliant environment, for - this reason a suitable container image is provided (see - [published packages](https://github.com/orgs/NNPDF/packages?repo_name=pineappl) - and the respective [`Containerfile`](./Containerfile)) - - Notice that the default container provided by - [pypa](https://github.com/pypa/manylinux) is not sufficient, since it does not - ship a C compiler (required to compile the `syn` crate). -- `macOS`: it just needs to be run in a macOS environment, see - [publishing workflow](https://github.com/NNPDF/pineappl/tree/master/.github/workflows/wheels.yml) -- `windows`: it just needs to be run in a windows environment, see - [publishing workflow](https://github.com/NNPDF/pineappl/tree/master/.github/workflows/wheels.yml) - -## `maturin` container image - -`maturin` image has its own version (following [semver](https://semver.org/)), -and: - -- it is based on `manylinux2014_x86_64` -- build wheels for a range of CPython versions (the actual one depends on the - `maturin` version inside the container) - -### Using `maturin` to compile for `manylinux` - -This is the easy part: you just need to download the -[image](https://github.com/NNPDF/pineappl/pkgs/container/maturin) and run with -your favorite container tool. - -Here the explicit commands with `podman` [[1]](#docker) - -```sh -podman pull ghcr.io/n3pdf/maturin:latest -podman run ghcr.io/n3pdf/maturin -podman cp :root/pineappl/pineappl_py/target/wheels/ . -``` - -Now wheels are available outside the container and can be uploaded in your -favorite way. - -#### Interactive use - -If you want to use the container environment interactively, you need to provide -an alternative entry point: - -```sh -podman run --entrypoint bash -it -``` - -### Create a new `maturin` image - -_Use case_: if a new rust or maturin version is released, it might be needed to -upgrade also those inside the `maturin` image (since they are pre-installed in -the image itself) - -To upgrade the build instructions ([_Containerfile_](./Containerfile)): - -- change `FROM` to choose a different manylinux base image (see the - [official source](https://github.com/pypa/manylinux)) -- change `ARG` for `MATURIN_TAG` to choose a different `maturin` version -- to change architecture both `FROM` and `ARG MATURIN_TAR=` have to be updated - from `x86_64` -- `rust` version is always taken to be the latest one at each build (so - rerunning the build **without changing** anything might generate a **different - image**) - -Once `Containerfile` has been updated then rerun: - -```sh -# inside pineappl/pineappl_py/package -podman build -t ghcr.io/n3pdf/maturin . -podman tag ghcr.io/n3pdf/maturin: -# login to GitHub registry with user credentials (not organization), see [2] -echo ${PAT} | podman login ghcr.io -u --password-stdin -# finally publish -podman push ghcr.io/n3pdf/maturin: -# and publish the new latest (all layers already available, it's just an alias) -podman push ghcr.io/n3pdf/maturin:latest -``` - -[1]: In the following I will use `podman` as the container -runtime for the examples. To use `docker` instead, you can simply replace -`podman -> docker`, they have compatible subcommands -[2]: official -[GitHub registry docs](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) diff --git a/pineappl_py/package/maturin b/pineappl_py/package/maturin deleted file mode 100755 index 2b33a9240..000000000 --- a/pineappl_py/package/maturin +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -export PATH=${HOME}/local/bin:${HOME}/.cargo/bin:${PATH} -cd ${HOME} -# clone pineappl code -git clone https://github.com/NNPDF/pineappl.git -# compile pineappl python package -cd pineappl/pineappl_py -maturin $@ From 01a264f4a748b5b81f93df513b718cbc390a022b Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 10:58:20 +0200 Subject: [PATCH 15/51] Remove obsolete `.gitignore` --- pineappl_py/docs/.gitignore | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 pineappl_py/docs/.gitignore diff --git a/pineappl_py/docs/.gitignore b/pineappl_py/docs/.gitignore deleted file mode 100644 index 1e6524a5f..000000000 --- a/pineappl_py/docs/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# autogenerated file -source/development/code_todos.rst -# Ignore auto generated module references -source/development/ekomark -# ignore temporary build files -_build/ -# Ignore generated sphinx-bibtex file -source/bibtex.json From ca2fb730cd04de8970df5ce5be36c6246f179ac6 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 11:09:40 +0200 Subject: [PATCH 16/51] Remove unused bibtex functionality --- pineappl_py/docs/source/conf.py | 3 --- pineappl_py/docs/source/refs.bib | 0 2 files changed, 3 deletions(-) delete mode 100644 pineappl_py/docs/source/refs.bib diff --git a/pineappl_py/docs/source/conf.py b/pineappl_py/docs/source/conf.py index 671aa7afb..988ed46e0 100644 --- a/pineappl_py/docs/source/conf.py +++ b/pineappl_py/docs/source/conf.py @@ -25,7 +25,6 @@ 'sphinx.ext.napoleon', 'sphinx.ext.todo', 'sphinx_rtd_theme', - 'sphinxcontrib.bibtex', ] autosummary_generate = True @@ -37,8 +36,6 @@ "pineko": ("https://github.com/NNPDF/pineko/%s", "pineko - %s"), } -bibtex_bibfiles = ["refs.bib"] - templates_path = ['_templates'] exclude_patterns = [] diff --git a/pineappl_py/docs/source/refs.bib b/pineappl_py/docs/source/refs.bib deleted file mode 100644 index e69de29bb..000000000 From 66922b274c6d7d24e7b3caa4a234184350c708d4 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 11:12:25 +0200 Subject: [PATCH 17/51] Add build instructions --- pineappl_py/README.md | 20 ++++++++++++++++++++ pineappl_py/requirements.txt | 28 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 pineappl_py/requirements.txt diff --git a/pineappl_py/README.md b/pineappl_py/README.md index da57beb55..e75e76575 100644 --- a/pineappl_py/README.md +++ b/pineappl_py/README.md @@ -12,3 +12,23 @@ For installation instructions see the [documentation]. [PyO3]: https://pyo3.rs [Rust API]: https://docs.rs/pineappl [documentation]: https://pineappl.readthedocs.io/en/latest/installation.html + +## Development + +Run + +```shell +python -m venv env && . env/bin/activate +pip install -r requirements.txt +maturin develop +``` + +to build and setup a new environment. + +Run + +```shell +cd docs && make html +``` + +to generate the documentation. diff --git a/pineappl_py/requirements.txt b/pineappl_py/requirements.txt new file mode 100644 index 000000000..7bd3ed9ba --- /dev/null +++ b/pineappl_py/requirements.txt @@ -0,0 +1,28 @@ +alabaster==0.7.16 +babel==2.16.0 +certifi==2024.7.4 +charset-normalizer==3.3.2 +docutils==0.20.1 +idna==3.7 +imagesize==1.4.1 +importlib-metadata==8.2.0 +jinja2==3.1.4 +MarkupSafe==2.1.5 +maturin==1.7.0 +numpy==1.26.4 +packaging==24.1 +pygments==2.18.0 +requests==2.32.3 +snowballstemmer==2.2.0 +sphinx==7.4.7 +sphinx-rtd-theme==2.0.0 +sphinxcontrib-applehelp==2.0.0 +sphinxcontrib-devhelp==2.0.0 +sphinxcontrib-htmlhelp==2.1.0 +sphinxcontrib-jquery==4.1 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==2.0.0 +sphinxcontrib-serializinghtml==2.0.0 +tomli==2.0.1 +urllib3==2.2.2 +zipp==3.20.0 From 0f04923c7e7f657bc5da3ac16d6576ae81556e68 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 12:48:52 +0300 Subject: [PATCH 18/51] Add more doc fixes --- pineappl_py/docs/source/conf.py | 2 -- pineappl_py/docs/source/implementation.rst | 3 +-- pineappl_py/docs/source/index.rst | 14 ++------------ 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/pineappl_py/docs/source/conf.py b/pineappl_py/docs/source/conf.py index 988ed46e0..5e7850799 100644 --- a/pineappl_py/docs/source/conf.py +++ b/pineappl_py/docs/source/conf.py @@ -31,9 +31,7 @@ autosummary_imported_members = True extlinks = { - "yadism": ("https://nnpdf.github.io/yadism/%s", "yadism - %s"), "rustdoc": ("https://docs.rs/pineappl/latest/pineappl/%s", "PineAPPL - %s"), - "pineko": ("https://github.com/NNPDF/pineko/%s", "pineko - %s"), } templates_path = ['_templates'] diff --git a/pineappl_py/docs/source/implementation.rst b/pineappl_py/docs/source/implementation.rst index 32a5e90ae..cf9dcece6 100644 --- a/pineappl_py/docs/source/implementation.rst +++ b/pineappl_py/docs/source/implementation.rst @@ -1,9 +1,8 @@ Implementation ============== -The wrapper is built using PyO3 to interface Rust to Python. This requires (for the moment) unfortunately a bit of overhead code so there exist four layers of code: +The wrapper is built using PyO3 to interface Rust to Python. - The original Rust library that actually provides all the functionality. Any true code should be placed here as this is shared by all interfaces. - The PyO3 wrapper objects written in Rust that define which methods are exposed to Python and that takes care of the type conversion from Python-understandable types to Rust types. - The PyO3 wrapper objects in Python which are an exact mirror of their Rust equivalent. This translation is provided by PyO3 and note that it also preserves the associated documentation. -- The additional Python wrappers around the raw PyO3 objects which provide convenience wrappers to cast arbitrary Python objects to objects that can actually used by PyO3. diff --git a/pineappl_py/docs/source/index.rst b/pineappl_py/docs/source/index.rst index 28160af76..cf92cdcda 100644 --- a/pineappl_py/docs/source/index.rst +++ b/pineappl_py/docs/source/index.rst @@ -8,7 +8,8 @@ PineAPPL is a computer library that makes it possible to produce fast-interpolat The :doc:`installation` instructions are given :doc:`here `. A practical example can be found in the ``example/`` subfolder of the `repository `_. -The Python wrapper is also used in :yadism:`\ ` and :pineko:`\ `. We also list some common :doc:`recipes` here. +The Python wrapper is also used in `yadism `_ and `pineko `_. +We also list some common :doc:`recipes` here. .. toctree:: :maxdepth: 1 @@ -20,14 +21,3 @@ The Python wrapper is also used in :yadism:`\ ` and :pineko:`\ `. We also list s implementation API indices - -.. important:: - - If you are looking for the methods of a specific class, be aware that part of - them are just passed to the underlying Rust object, whose class is the same - of the user-facing one, but prefixed with a ``Py``, e.g.: - :class:`pineappl.grid.Grid` and :class:`pineappl.pineappl.grid.PyGrid`. - - You will find the documentation of the unwrapped method in the raw ``Py`` - class, while part of the methods are wrapped and thus even documented in the - user-facing class. From 7606fb976fae8fcbcb0af19046c13f506b425301 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 13:18:22 +0300 Subject: [PATCH 19/51] Use preferred PyModule.add_subgrid. See https://docs.rs/pyo3/0.21.2/pyo3/types/struct.PyModule.html#method.add_submodule --- pineappl_py/src/bin.rs | 8 +++++--- pineappl_py/src/channel.rs | 8 +++++--- pineappl_py/src/evolution.rs | 8 +++++--- pineappl_py/src/fk_table.rs | 8 +++++--- pineappl_py/src/grid.rs | 8 +++++--- pineappl_py/src/import_only_subgrid.rs | 8 +++++--- pineappl_py/src/lib.rs | 17 ++++++++--------- pineappl_py/src/subgrid.rs | 8 +++++--- 8 files changed, 43 insertions(+), 30 deletions(-) diff --git a/pineappl_py/src/bin.rs b/pineappl_py/src/bin.rs index 41d3fe4c4..da0518016 100644 --- a/pineappl_py/src/bin.rs +++ b/pineappl_py/src/bin.rs @@ -1,3 +1,4 @@ +//! Binnning interface. use pineappl::bin::BinRemapper; use numpy::{PyArrayMethods, PyReadonlyArray1}; @@ -33,8 +34,9 @@ impl PyBinRemapper { } } -#[pymodule] -pub fn bin(_py: Python, m: &PyModule) -> PyResult<()> { +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "bin")?; m.add_class::()?; - Ok(()) + parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/channel.rs b/pineappl_py/src/channel.rs index 5b2c4a42c..115b07ad3 100644 --- a/pineappl_py/src/channel.rs +++ b/pineappl_py/src/channel.rs @@ -1,3 +1,4 @@ +//! Channel interface. use pineappl::boc::Channel; use pyo3::prelude::*; @@ -45,8 +46,9 @@ impl PyChannel { } } -#[pymodule] -pub fn channel(_py: Python, m: &PyModule) -> PyResult<()> { +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "channel")?; m.add_class::()?; - Ok(()) + parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index fd7f3b90c..005702de7 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -1,3 +1,4 @@ +//! Evolution interface. use numpy::{IntoPyArray, PyArray1}; use pineappl::evolution::{EvolveInfo, OperatorSliceInfo}; use pineappl::pids::PidBasis; @@ -106,10 +107,11 @@ impl PyEvolveInfo { } } -#[pymodule] -pub fn evolution(_py: Python, m: &PyModule) -> PyResult<()> { +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "evolution")?; m.add_class::()?; m.add_class::()?; m.add_class::()?; - Ok(()) + parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index fd2e6eb86..0542109ca 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -1,3 +1,4 @@ +//! FK table interface. use pineappl::convolutions::LumiCache; use pineappl::fk_table::{FkAssumptions, FkTable}; use pineappl::grid::Grid; @@ -296,9 +297,10 @@ impl PyFkTable { } } -#[pymodule] -pub fn fk_table(_py: Python, m: &PyModule) -> PyResult<()> { +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "fk_table")?; m.add_class::()?; m.add_class::()?; - Ok(()) + parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index e21dbbf3d..320ac24e9 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -1,3 +1,4 @@ +//! Grid interface. use ndarray::CowArray; use pineappl::boc::Order; use pineappl::convolutions::LumiCache; @@ -846,9 +847,10 @@ impl PyGrid { } } -#[pymodule] -pub fn grid(_py: Python, m: &PyModule) -> PyResult<()> { +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "grid")?; m.add_class::()?; m.add_class::()?; - Ok(()) + parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/import_only_subgrid.rs b/pineappl_py/src/import_only_subgrid.rs index ba1c6940f..2eadbdbea 100644 --- a/pineappl_py/src/import_only_subgrid.rs +++ b/pineappl_py/src/import_only_subgrid.rs @@ -1,3 +1,4 @@ +//! PyImportOnlySubgrid* interface. use super::subgrid::PySubgridEnum; use numpy::{PyArrayMethods, PyReadonlyArray1, PyReadonlyArray3}; @@ -150,9 +151,10 @@ impl PyImportOnlySubgridV1 { } } -#[pymodule] -pub fn import_only_subgrid(_py: Python, m: &PyModule) -> PyResult<()> { +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "import_only_subgrid")?; m.add_class::()?; m.add_class::()?; - Ok(()) + parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/lib.rs b/pineappl_py/src/lib.rs index dcd2e64d7..458382aa8 100644 --- a/pineappl_py/src/lib.rs +++ b/pineappl_py/src/lib.rs @@ -1,8 +1,7 @@ -// this is needed for PyO3 to work +//! Generate PyO3 interface. #![allow(unsafe_op_in_unsafe_fn)] use pyo3::prelude::*; -use pyo3::wrap_pymodule; pub mod bin; pub mod channel; @@ -17,13 +16,13 @@ pub mod subgrid; /// NOTE: this name has to match the one in Cargo.toml 'lib.name' #[pymodule] fn pineappl(m: &Bound<'_, PyModule>) -> PyResult<()> { - m.add_wrapped(wrap_pymodule!(bin::bin))?; - m.add_wrapped(wrap_pymodule!(grid::grid))?; - m.add_wrapped(wrap_pymodule!(import_only_subgrid::import_only_subgrid))?; - m.add_wrapped(wrap_pymodule!(evolution::evolution))?; - m.add_wrapped(wrap_pymodule!(channel::channel))?; - m.add_wrapped(wrap_pymodule!(fk_table::fk_table))?; - m.add_wrapped(wrap_pymodule!(subgrid::subgrid))?; + bin::register(m)?; + grid::register(m)?; + import_only_subgrid::register(m)?; + evolution::register(m)?; + channel::register(m)?; + fk_table::register(m)?; + subgrid::register(m)?; m.add("version", env!("CARGO_PKG_VERSION"))?; Ok(()) diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index 559a1d2e5..0be5354c7 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -1,3 +1,4 @@ +//! Subgrid interface. use ndarray::Array3; use numpy::{IntoPyArray, PyArray1, PyArray3}; use pineappl::subgrid::Mu2; @@ -232,10 +233,11 @@ impl PySubgridEnum { } } -#[pymodule] -pub fn subgrid(_py: Python, m: &PyModule) -> PyResult<()> { +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "subgrid")?; m.add_class::()?; m.add_class::()?; m.add_class::()?; - Ok(()) + parent_module.add_submodule(&m) } From 6f9005e468fbd3a2efdea7cf08ea6669094bb73c Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 14:14:22 +0300 Subject: [PATCH 20/51] Bring back sphinx.ext.autodoc --- pineappl_py/docs/source/conf.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/pineappl_py/docs/source/conf.py b/pineappl_py/docs/source/conf.py index 5e7850799..99ad83593 100644 --- a/pineappl_py/docs/source/conf.py +++ b/pineappl_py/docs/source/conf.py @@ -7,6 +7,8 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information import pineappl +import sys +import pathlib project = 'pineappl' copyright = '2020–2024, the PineAPPL team' @@ -18,7 +20,6 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.autosectionlabel', - 'sphinx.ext.autosummary', 'sphinx.ext.extlinks', 'sphinx.ext.inheritance_diagram', 'sphinx.ext.intersphinx', @@ -27,8 +28,6 @@ 'sphinx_rtd_theme', ] -autosummary_generate = True -autosummary_imported_members = True extlinks = { "rustdoc": ("https://docs.rs/pineappl/latest/pineappl/%s", "PineAPPL - %s"), @@ -42,3 +41,24 @@ html_theme = 'sphinx_rtd_theme' html_static_path = ['_static'] + + +here = pathlib.Path(__file__).absolute().parent + +# https://github.com/readthedocs/readthedocs.org/issues/1139#issuecomment-312626491 +def run_apidoc(_): + from sphinx.ext.apidoc import main # pylint: disable=import-outside-toplevel + + sys.path.append(str(here.parent)) + # analyse 'pineappl' + docs_dest = here / "modules" + import pineappl # pylint: disable=import-outside-toplevel + + # note that we can NOT point to the local directory (`here.parents[1] / "pineappl"`) + # but we need the package built by `maturin` and installed by `pip` + package = pathlib.Path(pineappl.__file__).parent / "pineappl" + main(["--module-first", "--no-toc", "-o", str(docs_dest), str(package)]) + + +def setup(app): + app.connect("builder-inited", run_apidoc) From 144e7917fb2673d89052d7996e1a99a3cad5f94d Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 15:39:44 +0300 Subject: [PATCH 21/51] Deactivate apidoc and use manual list --- pineappl_py/docs/Makefile | 3 +- pineappl_py/docs/source/conf.py | 27 +++++++-------- pineappl_py/docs/source/modules/pineappl.rst | 35 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/pineappl_py/docs/Makefile b/pineappl_py/docs/Makefile index ea76ec019..ee1f7c7e1 100644 --- a/pineappl_py/docs/Makefile +++ b/pineappl_py/docs/Makefile @@ -24,8 +24,9 @@ clean: rm -rf build rm -rf _build +# while apidoc does not work, we need to preserve that folder cleanall: clean - rm -rf $(PINEAPPLOUT) + # rm -rf $(PINEAPPLOUT) .PHONY: help Makefile diff --git a/pineappl_py/docs/source/conf.py b/pineappl_py/docs/source/conf.py index 99ad83593..61e3ef2b4 100644 --- a/pineappl_py/docs/source/conf.py +++ b/pineappl_py/docs/source/conf.py @@ -45,20 +45,21 @@ here = pathlib.Path(__file__).absolute().parent -# https://github.com/readthedocs/readthedocs.org/issues/1139#issuecomment-312626491 -def run_apidoc(_): - from sphinx.ext.apidoc import main # pylint: disable=import-outside-toplevel +# TODO: find a way to reactivate apidoc, which doesn't seem to work for the moment. +# # https://github.com/readthedocs/readthedocs.org/issues/1139#issuecomment-312626491 +# def run_apidoc(_): +# from sphinx.ext.apidoc import main # pylint: disable=import-outside-toplevel - sys.path.append(str(here.parent)) - # analyse 'pineappl' - docs_dest = here / "modules" - import pineappl # pylint: disable=import-outside-toplevel +# sys.path.append(str(here.parent)) +# # analyse 'pineappl' +# docs_dest = here / "modules" +# import pineappl # pylint: disable=import-outside-toplevel - # note that we can NOT point to the local directory (`here.parents[1] / "pineappl"`) - # but we need the package built by `maturin` and installed by `pip` - package = pathlib.Path(pineappl.__file__).parent / "pineappl" - main(["--module-first", "--no-toc", "-o", str(docs_dest), str(package)]) +# # note that we can NOT point to the local directory (`here.parents[1] / "pineappl"`) +# # but we need the package built by `maturin` and installed by `pip` +# package = pathlib.Path(pineappl.__file__).parent / "pineappl" +# main(["--module-first", "--no-toc", "-o", str(docs_dest), str(package)]) -def setup(app): - app.connect("builder-inited", run_apidoc) +# def setup(app): +# app.connect("builder-inited", run_apidoc) diff --git a/pineappl_py/docs/source/modules/pineappl.rst b/pineappl_py/docs/source/modules/pineappl.rst index b66bc2097..ec475f747 100644 --- a/pineappl_py/docs/source/modules/pineappl.rst +++ b/pineappl_py/docs/source/modules/pineappl.rst @@ -5,3 +5,38 @@ pineappl package :members: :undoc-members: :show-inheritance: + +.. automodule:: pineappl.bin + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: pineappl.channel + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: pineappl.evolution + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: pineappl.fk_table + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: pineappl.grid + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: pineappl.subgrid + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: pineappl.import_only_subgrid + :members: + :undoc-members: + :show-inheritance: From a0e1ae40462d669cda0d3a498775c79a14f1d909 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 15:43:54 +0300 Subject: [PATCH 22/51] Rename PyEvolveInfo --- CHANGELOG.md | 2 ++ pineappl_py/src/evolution.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d189eb43..aaf94acf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `pineappl.evolution.PidBasis` - Python API: replaced `pineappl.grid.PyOperatorSliceInfo` with `pineappl.evolution.OperatorSliceInfo` +- Python API: drop all `Py` prefix, e.g. `PyEvolveInfo` was renamed to + `EvolveInfo` ### Removed diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index 005702de7..f6eb6ec35 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -74,7 +74,7 @@ impl PyOperatorSliceInfo { } /// PyO3 wrapper to :rustdoc:`pineappl::evolution::EvolveInfo `. -#[pyclass] +#[pyclass(name = "EvolveInfo")] #[repr(transparent)] pub struct PyEvolveInfo { pub(crate) evolve_info: EvolveInfo, From 517747393733074ba25b6f989864a14011e74b9a Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 15:46:49 +0300 Subject: [PATCH 23/51] Fix links to Rust docs --- pineappl_py/src/evolution.rs | 2 +- pineappl_py/src/fk_table.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index f6eb6ec35..3df985f96 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -5,7 +5,7 @@ use pineappl::pids::PidBasis; use pyo3::prelude::*; -/// PyO3 wrapper to :rustdoc:`pineappl::pids::PidBasis `. +/// PyO3 wrapper to :rustdoc:`pineappl::pids::PidBasis `. #[pyclass(name = "PidBasis")] #[derive(Clone)] pub enum PyPidBasis { diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index 0542109ca..629c4ec6a 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -21,7 +21,7 @@ pub struct PyFkTable { pub(crate) fk_table: FkTable, } -/// PyO3 wrapper to :rustdoc:`pineappl::fk_table::PyFkAssumptions `. +/// PyO3 wrapper to :rustdoc:`pineappl::fk_table::PyFkAssumptions `. #[pyclass(name = "FkAssumptions")] #[repr(transparent)] pub struct PyFkAssumptions { From 8bce28c19f510c85331f04e9bd88a8bedbeeb3aa Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 15:51:47 +0300 Subject: [PATCH 24/51] Add python module import hacks and module docs --- pineappl_py/src/bin.rs | 2 ++ pineappl_py/src/channel.rs | 2 ++ pineappl_py/src/evolution.rs | 2 ++ pineappl_py/src/fk_table.rs | 2 ++ pineappl_py/src/grid.rs | 2 ++ pineappl_py/src/import_only_subgrid.rs | 2 ++ pineappl_py/src/subgrid.rs | 2 ++ 7 files changed, 14 insertions(+) diff --git a/pineappl_py/src/bin.rs b/pineappl_py/src/bin.rs index da0518016..b2ccbd7fd 100644 --- a/pineappl_py/src/bin.rs +++ b/pineappl_py/src/bin.rs @@ -37,6 +37,8 @@ impl PyBinRemapper { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "bin")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "Binning interface.")?; + pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.bin'] = m"); m.add_class::()?; parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/channel.rs b/pineappl_py/src/channel.rs index 115b07ad3..f7a494131 100644 --- a/pineappl_py/src/channel.rs +++ b/pineappl_py/src/channel.rs @@ -49,6 +49,8 @@ impl PyChannel { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "channel")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "Channel interface.")?; + pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.channel'] = m"); m.add_class::()?; parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index 3df985f96..de9216b27 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -110,6 +110,8 @@ impl PyEvolveInfo { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "evolution")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "Evolution interface.")?; + pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.evolution'] = m"); m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index 629c4ec6a..e2fb1d143 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -300,6 +300,8 @@ impl PyFkTable { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "fk_table")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "FK table interface.")?; + pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.fk_table'] = m"); m.add_class::()?; m.add_class::()?; parent_module.add_submodule(&m) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 320ac24e9..5c0181d6e 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -850,6 +850,8 @@ impl PyGrid { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "grid")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "Grid interface.")?; + pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.grid'] = m"); m.add_class::()?; m.add_class::()?; parent_module.add_submodule(&m) diff --git a/pineappl_py/src/import_only_subgrid.rs b/pineappl_py/src/import_only_subgrid.rs index 2eadbdbea..63d4784f3 100644 --- a/pineappl_py/src/import_only_subgrid.rs +++ b/pineappl_py/src/import_only_subgrid.rs @@ -154,6 +154,8 @@ impl PyImportOnlySubgridV1 { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "import_only_subgrid")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "ImportOnlySubgrid* interface.")?; + pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.import_only_subgrid'] = m"); m.add_class::()?; m.add_class::()?; parent_module.add_submodule(&m) diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index 0be5354c7..1cc16980b 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -236,6 +236,8 @@ impl PySubgridEnum { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "subgrid")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "Subgrid interface.")?; + pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.subgrid'] = m"); m.add_class::()?; m.add_class::()?; m.add_class::()?; From 872b01be23298bfdd586ca80461cc8c793785644 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 16:02:57 +0300 Subject: [PATCH 25/51] Improve docs --- pineappl_py/docs/source/implementation.rst | 8 -------- pineappl_py/docs/source/index.rst | 3 +-- pineappl_py/docs/source/recipes.rst | 14 ++++---------- 3 files changed, 5 insertions(+), 20 deletions(-) delete mode 100644 pineappl_py/docs/source/implementation.rst diff --git a/pineappl_py/docs/source/implementation.rst b/pineappl_py/docs/source/implementation.rst deleted file mode 100644 index cf9dcece6..000000000 --- a/pineappl_py/docs/source/implementation.rst +++ /dev/null @@ -1,8 +0,0 @@ -Implementation -============== - -The wrapper is built using PyO3 to interface Rust to Python. - -- The original Rust library that actually provides all the functionality. Any true code should be placed here as this is shared by all interfaces. -- The PyO3 wrapper objects written in Rust that define which methods are exposed to Python and that takes care of the type conversion from Python-understandable types to Rust types. -- The PyO3 wrapper objects in Python which are an exact mirror of their Rust equivalent. This translation is provided by PyO3 and note that it also preserves the associated documentation. diff --git a/pineappl_py/docs/source/index.rst b/pineappl_py/docs/source/index.rst index cf92cdcda..600c36b30 100644 --- a/pineappl_py/docs/source/index.rst +++ b/pineappl_py/docs/source/index.rst @@ -1,7 +1,7 @@ Welcome to PineAPPL =================== -This is the Python wrapper for the `Rust PineAPPL library `_. +This is the Python wrapper for the `Rust PineAPPL library `_ using `PyO3 `_. PineAPPL is a computer library that makes it possible to produce fast-interpolation grids for fitting parton distribution functions (PDFs) including corrections of strong and electroweak origin. @@ -18,6 +18,5 @@ We also list some common :doc:`recipes` here. installation recipes - implementation API indices diff --git a/pineappl_py/docs/source/recipes.rst b/pineappl_py/docs/source/recipes.rst index f026bf4ea..a599a888a 100644 --- a/pineappl_py/docs/source/recipes.rst +++ b/pineappl_py/docs/source/recipes.rst @@ -13,7 +13,7 @@ How can I convolve a given PineAPPL grid with my PDF? import lhapdf g = pineappl.grid.Grid.read("path/to/grid.pineappl.lz4") pdf = lhapdf.mkPDF("YourPDF", 0) - bins = g.convolve(pdf.xfxQ2, pdf.xfxQ2, pdf.alphasQ2) + bins = g.convolve_with_one(2212, pdf.xfxQ2, pdf.alphasQ2) If the grid is actually an FkTable just replace @@ -23,16 +23,11 @@ If the grid is actually an FkTable just replace .. note:: - For the :meth:`pineappl.pineappl.PyGrid.read` function, both ``.pineappl`` + For the :meth:`pineappl.grid.Grid.read` function, both ``.pineappl`` and ``.pineappl.lz4`` extensions are acceptable, as long as they are consistent (without ``.lz4`` the grid is assumed not to be compressed, with it is assumed compressed). - This is asymmetric with respect to the - :meth:`pineappl.pineappl.PyGrid.write` function, in which the function will - refuse to guess, so another version is provided to write a compressed grid, - :meth:`pineappl.pineappl.PyGrid.write_lz4` - How can I edit a grid? ---------------------- @@ -60,9 +55,8 @@ change even the bins themselves. remapper = pineappl.bin.BinRemapper(normalizations, limits) g.set_remapper(remapper) -For more details about :class:`pineappl.bin.BinRemapper` check also the `Rust -documentation -`_, e.g. +For more details about :class:`pineappl.bin.BinRemapper` check also +the Rust documentation of :rustdoc:`pineappl::bin::BinRemapper `, e.g. on how to treat multidimensional distributions. How can I get the bin configurations from a given PineAPPL grid? From 5279c235bbb0a5e41aca921542fe99d2fd5c221f Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 15:03:06 +0200 Subject: [PATCH 26/51] Fix more broken links --- pineappl_py/src/fk_table.rs | 2 +- pineappl_py/src/grid.rs | 2 +- pineappl_py/src/subgrid.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index e2fb1d143..072b7e658 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -21,7 +21,7 @@ pub struct PyFkTable { pub(crate) fk_table: FkTable, } -/// PyO3 wrapper to :rustdoc:`pineappl::fk_table::PyFkAssumptions `. +/// PyO3 wrapper to :rustdoc:`pineappl::fk_table::FkAssumptions `. #[pyclass(name = "FkAssumptions")] #[repr(transparent)] pub struct PyFkAssumptions { diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 5c0181d6e..432762eb1 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -25,7 +25,7 @@ use pyo3::exceptions::PyValueError; use pyo3::prelude::*; use pyo3::types::PyIterator; -/// PyO3 wrapper to :rustdoc:`pineappl::grid::Order `. +/// PyO3 wrapper to :rustdoc:`pineappl::boc::Order `. #[pyclass(name = "Order")] #[repr(transparent)] pub struct PyOrder { diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index 1cc16980b..cad083b3f 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -5,7 +5,7 @@ use pineappl::subgrid::Mu2; use pineappl::subgrid::{Subgrid, SubgridEnum, SubgridParams}; use pyo3::prelude::*; -/// PyO3 wrapper to :rustdoc:`pineappl::subgrid::SubgridParams ` +/// PyO3 wrapper to :rustdoc:`pineappl::subgrid::SubgridParams ` #[pyclass(name = "SubgridParams")] #[repr(transparent)] pub struct PySubgridParams { From 759f7fa0057978a401747a13ca114752d4849776 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 15:09:29 +0200 Subject: [PATCH 27/51] Run `cargo fmt` --- pineappl_py/src/fk_table.rs | 6 +++++- pineappl_py/src/grid.rs | 6 +++++- pineappl_py/src/subgrid.rs | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index 072b7e658..0c7347786 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -301,7 +301,11 @@ impl PyFkTable { pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "fk_table")?; m.setattr(pyo3::intern!(m.py(), "__doc__"), "FK table interface.")?; - pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.fk_table'] = m"); + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.fk_table'] = m" + ); m.add_class::()?; m.add_class::()?; parent_module.add_submodule(&m) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 432762eb1..76c40e287 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -851,7 +851,11 @@ impl PyGrid { pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "grid")?; m.setattr(pyo3::intern!(m.py(), "__doc__"), "Grid interface.")?; - pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.grid'] = m"); + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.grid'] = m" + ); m.add_class::()?; m.add_class::()?; parent_module.add_submodule(&m) diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index cad083b3f..48f39770d 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -237,7 +237,11 @@ impl PySubgridEnum { pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "subgrid")?; m.setattr(pyo3::intern!(m.py(), "__doc__"), "Subgrid interface.")?; - pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.subgrid'] = m"); + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.subgrid'] = m" + ); m.add_class::()?; m.add_class::()?; m.add_class::()?; From 4c53c713b6244d767e4a86fc4f3cbfd602b7e3f8 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 15:11:42 +0200 Subject: [PATCH 28/51] Reformat `CHANGELOG.md` --- CHANGELOG.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aaf94acf1..538f63d42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,18 +15,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Python API: dropped top-level Python interface layer -- Python API: renamed `lumi` to `channel` in PyO3 Python interface. - This concerns 1) the argument names of `convolute_with_one` and - similar functions; 2) the module `pineappl.lumi` was moved to - `pineappl.channel`; 3) the class `LumiEntry` was renamed to `Channel` -- Python API: `.into()` needs to be explicitly called on subgrids when - calling `pineappl.grid.set_subgrid()` +- Python API: renamed `lumi` to `channel` in PyO3 Python interface. This + concerns 1) the argument names of `convolute_with_one` and similar functions; + 2) the module `pineappl.lumi` was moved to `pineappl.channel`; 3) the class + `LumiEntry` was renamed to `Channel` +- Python API: `.into()` needs to be explicitly called on subgrids when calling + `pineappl.grid.set_subgrid()` - Python API: replaced `pineappl.grid.PyPidBasis` with `pineappl.evolution.PidBasis` - Python API: replaced `pineappl.grid.PyOperatorSliceInfo` with `pineappl.evolution.OperatorSliceInfo` -- Python API: drop all `Py` prefix, e.g. `PyEvolveInfo` was renamed to - `EvolveInfo` +- Python API: drop all `Py` prefixes, for instance `PyEvolveInfo` was renamed + to `EvolveInfo` ### Removed From 09460b6ec1f7502e1c72e75e0ffc1f4cd34b9af4 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 16:24:53 +0300 Subject: [PATCH 29/51] Readd docs/gitignore --- pineappl_py/docs/.gitignore | 7 +++++++ pineappl_py/docs/Makefile | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 pineappl_py/docs/.gitignore diff --git a/pineappl_py/docs/.gitignore b/pineappl_py/docs/.gitignore new file mode 100644 index 000000000..f6b158ddc --- /dev/null +++ b/pineappl_py/docs/.gitignore @@ -0,0 +1,7 @@ +# Ignore auto generated module references +# TODO: while apidoc does not work, we need to preserve that folder +# source/modules +# ignore temporary build files +build/ +# Ignore generated sphinx-bibtex file +source/bibtex.json diff --git a/pineappl_py/docs/Makefile b/pineappl_py/docs/Makefile index ee1f7c7e1..db4a541c0 100644 --- a/pineappl_py/docs/Makefile +++ b/pineappl_py/docs/Makefile @@ -24,7 +24,7 @@ clean: rm -rf build rm -rf _build -# while apidoc does not work, we need to preserve that folder +# TODO: while apidoc does not work, we need to preserve that folder cleanall: clean # rm -rf $(PINEAPPLOUT) From 53fba7ba5354fe7179f6969f896329ea00efecc0 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 16:30:02 +0300 Subject: [PATCH 30/51] Rename API header --- pineappl_py/docs/source/modules/pineappl.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pineappl_py/docs/source/modules/pineappl.rst b/pineappl_py/docs/source/modules/pineappl.rst index ec475f747..3bbe4b8ed 100644 --- a/pineappl_py/docs/source/modules/pineappl.rst +++ b/pineappl_py/docs/source/modules/pineappl.rst @@ -1,5 +1,5 @@ -pineappl package -================ +PineAPPL's Python API +===================== .. automodule:: pineappl :members: From 2727c4cba2212cac50da93a2b2bd31f90da7c2a5 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 16:38:24 +0300 Subject: [PATCH 31/51] Shuffle docs/gitignoe upwards --- pineappl_py/.gitignore | 9 +++++++-- pineappl_py/docs/.gitignore | 7 ------- 2 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 pineappl_py/docs/.gitignore diff --git a/pineappl_py/.gitignore b/pineappl_py/.gitignore index 21abbfe8b..2452cb594 100644 --- a/pineappl_py/.gitignore +++ b/pineappl_py/.gitignore @@ -21,8 +21,13 @@ coverage.xml .coverage # Sphinx documentation -docs/_build/ -doc/_build/ +# Ignore auto generated module references +# TODO: while apidoc does not work, we need to preserve that folder +# docs/source/modules +# ignore temporary build files +docs/build/ +# Ignore generated sphinx-bibtex file +docs/source/bibtex.json # Environments .env diff --git a/pineappl_py/docs/.gitignore b/pineappl_py/docs/.gitignore deleted file mode 100644 index f6b158ddc..000000000 --- a/pineappl_py/docs/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Ignore auto generated module references -# TODO: while apidoc does not work, we need to preserve that folder -# source/modules -# ignore temporary build files -build/ -# Ignore generated sphinx-bibtex file -source/bibtex.json From 19e15646962c97244f1e5d4b7446a60e1fcce113 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 16:43:06 +0300 Subject: [PATCH 32/51] Drop requirements.txt --- pineappl_py/README.md | 12 ++++++++++-- pineappl_py/requirements.txt | 28 ---------------------------- 2 files changed, 10 insertions(+), 30 deletions(-) delete mode 100644 pineappl_py/requirements.txt diff --git a/pineappl_py/README.md b/pineappl_py/README.md index e75e76575..1bbf34d93 100644 --- a/pineappl_py/README.md +++ b/pineappl_py/README.md @@ -19,11 +19,19 @@ Run ```shell python -m venv env && . env/bin/activate -pip install -r requirements.txt +pip install .[docs] +``` + +to setup a new environment. + + +Run + +```shell maturin develop ``` -to build and setup a new environment. +to build the project. Run diff --git a/pineappl_py/requirements.txt b/pineappl_py/requirements.txt deleted file mode 100644 index 7bd3ed9ba..000000000 --- a/pineappl_py/requirements.txt +++ /dev/null @@ -1,28 +0,0 @@ -alabaster==0.7.16 -babel==2.16.0 -certifi==2024.7.4 -charset-normalizer==3.3.2 -docutils==0.20.1 -idna==3.7 -imagesize==1.4.1 -importlib-metadata==8.2.0 -jinja2==3.1.4 -MarkupSafe==2.1.5 -maturin==1.7.0 -numpy==1.26.4 -packaging==24.1 -pygments==2.18.0 -requests==2.32.3 -snowballstemmer==2.2.0 -sphinx==7.4.7 -sphinx-rtd-theme==2.0.0 -sphinxcontrib-applehelp==2.0.0 -sphinxcontrib-devhelp==2.0.0 -sphinxcontrib-htmlhelp==2.1.0 -sphinxcontrib-jquery==4.1 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-qthelp==2.0.0 -sphinxcontrib-serializinghtml==2.0.0 -tomli==2.0.1 -urllib3==2.2.2 -zipp==3.20.0 From 77995e07d76eb944780ae750e76404f2c6cc2bf0 Mon Sep 17 00:00:00 2001 From: Felix Hekhorn Date: Wed, 14 Aug 2024 16:44:33 +0300 Subject: [PATCH 33/51] Apply suggestions from code review --- pineappl_py/.gitignore | 2 -- pineappl_py/docs/source/conf.py | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pineappl_py/.gitignore b/pineappl_py/.gitignore index 2452cb594..83eb351cd 100644 --- a/pineappl_py/.gitignore +++ b/pineappl_py/.gitignore @@ -26,8 +26,6 @@ coverage.xml # docs/source/modules # ignore temporary build files docs/build/ -# Ignore generated sphinx-bibtex file -docs/source/bibtex.json # Environments .env diff --git a/pineappl_py/docs/source/conf.py b/pineappl_py/docs/source/conf.py index 61e3ef2b4..8c3b56cf3 100644 --- a/pineappl_py/docs/source/conf.py +++ b/pineappl_py/docs/source/conf.py @@ -43,9 +43,9 @@ html_static_path = ['_static'] -here = pathlib.Path(__file__).absolute().parent - # TODO: find a way to reactivate apidoc, which doesn't seem to work for the moment. + +# here = pathlib.Path(__file__).absolute().parent # # https://github.com/readthedocs/readthedocs.org/issues/1139#issuecomment-312626491 # def run_apidoc(_): # from sphinx.ext.apidoc import main # pylint: disable=import-outside-toplevel From 6895357718ef53ccda0fea63d0fa9b87ffcb0329 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 16:20:03 +0200 Subject: [PATCH 34/51] Fix installation instructions --- pineappl_py/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pineappl_py/README.md b/pineappl_py/README.md index 1bbf34d93..b4ff694dc 100644 --- a/pineappl_py/README.md +++ b/pineappl_py/README.md @@ -19,7 +19,7 @@ Run ```shell python -m venv env && . env/bin/activate -pip install .[docs] +pip install maturin ``` to setup a new environment. @@ -36,6 +36,7 @@ to build the project. Run ```shell +maturin develop -E docs cd docs && make html ``` From 03e7d6ac363ea10e9afa2ab7377503782fd58da7 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 16:20:18 +0200 Subject: [PATCH 35/51] Remove unneeded dependency --- pineappl_py/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pineappl_py/pyproject.toml b/pineappl_py/pyproject.toml index cb0886107..7c861e62b 100644 --- a/pineappl_py/pyproject.toml +++ b/pineappl_py/pyproject.toml @@ -28,7 +28,6 @@ cli = ["pineappl-cli"] docs = [ "sphinx>=6.2.1", "sphinx_rtd_theme>=1.2.2", - "sphinxcontrib-bibtex>=2.5.0", "nbsphinx>=0.9.2", ] test = ["pytest", "pytest-cov"] From 645388786430b15b22234d54142463d625e4cd2f Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 16:29:37 +0200 Subject: [PATCH 36/51] Remove yet another unneeded dependency Co-authored-by: Felix Hekhorn --- pineappl_py/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pineappl_py/pyproject.toml b/pineappl_py/pyproject.toml index 7c861e62b..2b0864f26 100644 --- a/pineappl_py/pyproject.toml +++ b/pineappl_py/pyproject.toml @@ -28,7 +28,6 @@ cli = ["pineappl-cli"] docs = [ "sphinx>=6.2.1", "sphinx_rtd_theme>=1.2.2", - "nbsphinx>=0.9.2", ] test = ["pytest", "pytest-cov"] From b0de152dfe81591158f25b3b1d6602c150dfc919 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 17:11:10 +0200 Subject: [PATCH 37/51] Write more detailed instructions for Python development --- pineappl_py/README.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/pineappl_py/README.md b/pineappl_py/README.md index b4ff694dc..51d3668f9 100644 --- a/pineappl_py/README.md +++ b/pineappl_py/README.md @@ -19,11 +19,20 @@ Run ```shell python -m venv env && . env/bin/activate -pip install maturin ``` -to setup a new environment. +to setup a new environment and check that `pip --version` returns at least `pip +22.0 from ...`. If not, upgrade `pip` via + +```shell +pip install -U pip +``` +Next, install the needed dependencies: + +```shell +pip install maturin +``` Run @@ -31,13 +40,21 @@ Run maturin develop ``` -to build the project. +to build the project, which also install it into the environment so that it can +be used in Python project using the same environment. -Run +### Documentation + +Run the following once to install the documentation's dependencies: + +```shell +pip install .[docs] +``` + +Then run ```shell -maturin develop -E docs -cd docs && make html +( cd docs && make clean html ) ``` to generate the documentation. From 43485a6ff58bc29bbee3806b9ced98e00287e3d9 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 17:13:37 +0200 Subject: [PATCH 38/51] Add some small fixes to Python's `README.md` file --- pineappl_py/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pineappl_py/README.md b/pineappl_py/README.md index 51d3668f9..475831506 100644 --- a/pineappl_py/README.md +++ b/pineappl_py/README.md @@ -28,7 +28,7 @@ to setup a new environment and check that `pip --version` returns at least `pip pip install -U pip ``` -Next, install the needed dependencies: +Next, install `maturin`: ```shell pip install maturin @@ -40,8 +40,8 @@ Run maturin develop ``` -to build the project, which also install it into the environment so that it can -be used in Python project using the same environment. +to build the project, which also installs it into the environment so that it +can be used in Python projects that use the same environment. ### Documentation From ba7aa7a47d661bb54cc589ef5514e845deca3f9c Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Wed, 14 Aug 2024 17:25:39 +0200 Subject: [PATCH 39/51] Add single quotes in `pip install ...` Co-authored-by: Alessandro Candido --- pineappl_py/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pineappl_py/README.md b/pineappl_py/README.md index 475831506..a91bb744e 100644 --- a/pineappl_py/README.md +++ b/pineappl_py/README.md @@ -48,7 +48,7 @@ can be used in Python projects that use the same environment. Run the following once to install the documentation's dependencies: ```shell -pip install .[docs] +pip install '.[docs]' ``` Then run From 3bf331d98ac0aa416ba37aa8d9796e745ddc66ef Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 08:34:26 +0200 Subject: [PATCH 40/51] Run `black` --- pineappl_py/tests/test_sugrid.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pineappl_py/tests/test_sugrid.py b/pineappl_py/tests/test_sugrid.py index 32055ea21..f4fedff2f 100644 --- a/pineappl_py/tests/test_sugrid.py +++ b/pineappl_py/tests/test_sugrid.py @@ -46,7 +46,9 @@ def fake_importonlysubgrid(self): Q2s = np.linspace(10, 20, 2) mu2s = [tuple([q2, q2]) for q2 in Q2s] array = np.random.rand(len(Q2s), len(x1s), len(x2s)) - subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV2(array, mu2s, x1s, x2s) + subgrid = pineappl.import_only_subgrid.ImportOnlySubgridV2( + array, mu2s, x1s, x2s + ) return subgrid, [x1s, x2s, mu2s, array] def test_subgrid_methods(self): @@ -67,7 +69,7 @@ def test_to_array3(self): test_subgrid, infos = self.fake_importonlysubgrid() _, _, _, array = (obj for obj in infos) grid.set_subgrid(0, 0, 0, test_subgrid.into()) - extr_subgrid = grid.subgrid(0,0,0) + extr_subgrid = grid.subgrid(0, 0, 0) test_array = extr_subgrid.to_array3() print(test_array) print(array) From 3a8064b16a5ab652721038cc9c445951176f5e42 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:18:34 +0200 Subject: [PATCH 41/51] Fix most compilation warnings --- pineappl_py/src/evolution.rs | 2 ++ pineappl_py/src/fk_table.rs | 8 ++++---- pineappl_py/src/grid.rs | 2 +- pineappl_py/src/subgrid.rs | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index de9216b27..d7ecf17ef 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -9,7 +9,9 @@ use pyo3::prelude::*; #[pyclass(name = "PidBasis")] #[derive(Clone)] pub enum PyPidBasis { + /// PDG Monte Carlo IDs. Pdg, + /// NNPDF's evolution basis IDs. Evol, } diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index 0c7347786..08328dcd7 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -261,15 +261,15 @@ impl PyFkTable { pub fn convolve_with_two<'py>( &self, pdg_id1: i32, - xfx1: &PyAny, + xfx1: &Bound<'py, PyAny>, pdg_id2: i32, - xfx2: &PyAny, + xfx2: &Bound<'py, PyAny>, bin_indices: Option>, channel_mask: Option>, py: Python<'py>, ) -> Bound<'py, PyArray1> { - let mut xfx1 = |id, x, q2| f64::extract(xfx1.call1((id, x, q2)).unwrap()).unwrap(); - let mut xfx2 = |id, x, q2| f64::extract(xfx2.call1((id, x, q2)).unwrap()).unwrap(); + let mut xfx1 = |id, x, q2| xfx1.call1((id, x, q2)).unwrap().extract().unwrap(); + let mut xfx2 = |id, x, q2| xfx2.call1((id, x, q2)).unwrap().extract().unwrap(); let mut alphas = |_| 1.0; let mut lumi_cache = LumiCache::with_two(pdg_id1, &mut xfx1, pdg_id2, &mut xfx2, &mut alphas); diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 76c40e287..ec9bb2e11 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -7,7 +7,7 @@ use pineappl::grid::{Grid, Ntuple}; use super::bin::PyBinRemapper; use super::channel::PyChannel; -use super::evolution::{PyEvolveInfo, PyOperatorSliceInfo, PyPidBasis}; +use super::evolution::{PyEvolveInfo, PyOperatorSliceInfo}; use super::fk_table::PyFkTable; use super::subgrid::{PySubgridEnum, PySubgridParams}; diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index 48f39770d..13dda42b0 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -139,7 +139,7 @@ impl PySubgridParams { #[pyclass(name = "Mu2")] #[repr(transparent)] pub struct PyMu2 { - pub mu2: Mu2, + pub(crate) mu2: Mu2, } #[pymethods] From a7d461d22f36ab6b7a6a50f9b2221c01f3dcff4b Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:21:42 +0200 Subject: [PATCH 42/51] Remove deprecated methods --- pineappl_py/src/grid.rs | 96 +---------------------------------------- 1 file changed, 2 insertions(+), 94 deletions(-) diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index ec9bb2e11..2c485a5b6 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -2,7 +2,7 @@ use ndarray::CowArray; use pineappl::boc::Order; use pineappl::convolutions::LumiCache; -use pineappl::evolution::{AlphasTable, OperatorInfo}; +use pineappl::evolution::AlphasTable; use pineappl::grid::{Grid, Ntuple}; use super::bin::PyBinRemapper; @@ -12,9 +12,7 @@ use super::fk_table::PyFkTable; use super::subgrid::{PySubgridEnum, PySubgridParams}; use itertools::izip; -use numpy::{ - IntoPyArray, PyArray1, PyArrayMethods, PyReadonlyArray1, PyReadonlyArray4, PyReadonlyArray5, -}; +use numpy::{IntoPyArray, PyArray1, PyArrayMethods, PyReadonlyArray1, PyReadonlyArray4}; use std::collections::HashMap; use std::fs::File; @@ -449,82 +447,6 @@ impl PyGrid { .into_pyarray_bound(py) } - /// Convolve with an evolution operator. - /// - /// Parameters - /// ---------- - /// operator : numpy.ndarray(int, rank=5) - /// evolution tensor - /// fac0 : float - /// reference scale - /// pids0 : numpy.ndarray(int) - /// sorting of the particles in the tensor for final FkTable - /// x0 : numpy.ndarray(float) - /// final FKTable interpolation grid - /// fac1 : numpy.ndarray(float) - /// list of factorization scales - /// pids1 : numpy.ndarray(int) - /// sorting of the particles in the grid - /// x1 : numpy.ndarray(float) - /// interpolation grid at process level - /// ren1 : numpy.ndarray(float) - /// list of renormalization scales - /// alphas : numpy.ndarray(float) - /// list with :math:`\alpha_s(Q2)` for the process scales - /// xi : (float, float) - /// factorization and renormalization variation - /// pid_basis : str - /// type of channel identifier - /// order_mask : numpy.ndarray(bool) - /// boolean mask to activate orders - /// - /// Returns - /// ------- - /// PyFkTable : - /// produced FK table - #[deprecated(since = "0.7.4", note = "use evolve_with_slice_iter instead")] - pub fn evolve( - &self, - operator: PyReadonlyArray5, - fac0: f64, - pids0: PyReadonlyArray1, - x0: PyReadonlyArray1, - fac1: PyReadonlyArray1, - pids1: PyReadonlyArray1, - x1: PyReadonlyArray1, - ren1: PyReadonlyArray1, - alphas: PyReadonlyArray1, - xi: (f64, f64), - pid_basis: String, - order_mask: PyReadonlyArray1, - ) -> PyFkTable { - let op_info = OperatorInfo { - fac0: fac0, - pids0: pids0.to_vec().unwrap(), - x0: x0.to_vec().unwrap(), - fac1: fac1.to_vec().unwrap(), - pids1: pids1.to_vec().unwrap(), - x1: x1.to_vec().unwrap(), - ren1: ren1.to_vec().unwrap(), - alphas: alphas.to_vec().unwrap(), - xir: xi.0, - xif: xi.1, - pid_basis: pid_basis.parse().unwrap(), - }; - - let evolved_grid = self - .grid - .evolve( - operator.as_array(), - &op_info, - order_mask.as_slice().unwrap(), - ) - .expect("Nothing returned from evolution."); - PyFkTable { - fk_table: evolved_grid, - } - } - /// Collect information for convolution with an evolution operator. /// /// Parameters @@ -707,20 +629,6 @@ impl PyGrid { } } - /// Merge with another grid, loaded from file. - /// - /// Note - /// ---- - /// For a current limitation with the implementation of the bound object `Grid` is not possible - /// to operate with two `Grid`s in memory, since is not possible to pass a `Grid` by argument - #[deprecated = "Deprecated in favor of PyGrid::merge"] - pub fn merge_from_file(&mut self, path: PathBuf) -> PyResult<()> { - match self.grid.merge(Self::read(path).grid) { - Ok(()) => Ok(()), - Err(x) => Err(PyValueError::new_err(format!("{:?}", x))), - } - } - /// Extract the number of dimensions for bins. /// /// E.g.: two differential cross-sections will return 2. From 024bcd6defcbcf1920488a81e30ffaccdb9101cb Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:21:56 +0200 Subject: [PATCH 43/51] Run `cargo fmt` --- pineappl_py/src/bin.rs | 6 +++++- pineappl_py/src/channel.rs | 6 +++++- pineappl_py/src/evolution.rs | 6 +++++- pineappl_py/src/import_only_subgrid.rs | 11 +++++++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/pineappl_py/src/bin.rs b/pineappl_py/src/bin.rs index b2ccbd7fd..445b9428f 100644 --- a/pineappl_py/src/bin.rs +++ b/pineappl_py/src/bin.rs @@ -38,7 +38,11 @@ impl PyBinRemapper { pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "bin")?; m.setattr(pyo3::intern!(m.py(), "__doc__"), "Binning interface.")?; - pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.bin'] = m"); + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.bin'] = m" + ); m.add_class::()?; parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/channel.rs b/pineappl_py/src/channel.rs index f7a494131..3f257430a 100644 --- a/pineappl_py/src/channel.rs +++ b/pineappl_py/src/channel.rs @@ -50,7 +50,11 @@ impl PyChannel { pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "channel")?; m.setattr(pyo3::intern!(m.py(), "__doc__"), "Channel interface.")?; - pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.channel'] = m"); + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.channel'] = m" + ); m.add_class::()?; parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index d7ecf17ef..2835e8cf9 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -113,7 +113,11 @@ impl PyEvolveInfo { pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "evolution")?; m.setattr(pyo3::intern!(m.py(), "__doc__"), "Evolution interface.")?; - pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.evolution'] = m"); + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.evolution'] = m" + ); m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/pineappl_py/src/import_only_subgrid.rs b/pineappl_py/src/import_only_subgrid.rs index 63d4784f3..fa52b132d 100644 --- a/pineappl_py/src/import_only_subgrid.rs +++ b/pineappl_py/src/import_only_subgrid.rs @@ -154,8 +154,15 @@ impl PyImportOnlySubgridV1 { /// Register submodule in parent. pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { let m = PyModule::new_bound(parent_module.py(), "import_only_subgrid")?; - m.setattr(pyo3::intern!(m.py(), "__doc__"), "ImportOnlySubgrid* interface.")?; - pyo3::py_run!(parent_module.py(), m, "import sys; sys.modules['pineappl.import_only_subgrid'] = m"); + m.setattr( + pyo3::intern!(m.py(), "__doc__"), + "ImportOnlySubgrid* interface.", + )?; + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.import_only_subgrid'] = m" + ); m.add_class::()?; m.add_class::()?; parent_module.add_submodule(&m) From ea9d1577b44f8f3ad185e4f7c4cacb9bfe4db05f Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:32:59 +0200 Subject: [PATCH 44/51] Move structs into modules corresponding to Rust modules --- pineappl_py/src/boc.rs | 149 +++++++++++++++++++++++++++++ pineappl_py/src/channel.rs | 60 ------------ pineappl_py/src/evolution.rs | 23 +---- pineappl_py/src/grid.rs | 87 +---------------- pineappl_py/src/lib.rs | 6 +- pineappl_py/tests/test_boc.py | 7 ++ pineappl_py/tests/test_channel.py | 7 -- pineappl_py/tests/test_fk_table.py | 4 +- pineappl_py/tests/test_grid.py | 2 +- pineappl_py/tests/test_sugrid.py | 4 +- 10 files changed, 168 insertions(+), 181 deletions(-) create mode 100644 pineappl_py/src/boc.rs delete mode 100644 pineappl_py/src/channel.rs create mode 100644 pineappl_py/tests/test_boc.py delete mode 100644 pineappl_py/tests/test_channel.py diff --git a/pineappl_py/src/boc.rs b/pineappl_py/src/boc.rs new file mode 100644 index 000000000..aadad4611 --- /dev/null +++ b/pineappl_py/src/boc.rs @@ -0,0 +1,149 @@ +//! Interface for bins, orders and channels. + +use numpy::{IntoPyArray, PyArray1}; +use pineappl::boc::{Channel, Order}; + +use pyo3::prelude::*; + +/// PyO3 wrapper to :rustdoc:`pineappl::boc::Channel `. +/// +/// Each entry consists of a tuple, which contains, in the following order: +/// +/// 1. the PDG id of the first incoming parton +/// 2. the PDG id of the second parton +/// 3. a numerical factor that will multiply the result for this specific combination. +#[pyclass(name = "Channel")] +#[repr(transparent)] +pub struct PyChannel { + pub(crate) entry: Channel, +} + +impl PyChannel { + pub(crate) fn new(entry: Channel) -> Self { + Self { entry } + } +} + +#[pymethods] +impl PyChannel { + /// Constructor. + /// + /// Parameters + /// ---------- + /// entry: list(tuple(int, int, float)) + /// channel configuration + #[new] + pub fn new_entry(entry: Vec<(i32, i32, f64)>) -> Self { + Self::new(Channel::new(entry)) + } + + /// Get list representation. + /// + /// Returns + /// ------- + /// list(tuple(int,int,float)) : + /// list representation + pub fn into_array(&self) -> Vec<(i32, i32, f64)> { + self.entry.entry().to_vec() + } +} + +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "boc")?; + m.setattr( + pyo3::intern!(m.py(), "__doc__"), + "Interface for bins, orders and channels.", + )?; + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.channel'] = m" + ); + m.add_class::()?; + parent_module.add_submodule(&m) +} + +/// PyO3 wrapper to :rustdoc:`pineappl::boc::Order `. +#[pyclass(name = "Order")] +#[repr(transparent)] +pub struct PyOrder { + pub(crate) order: Order, +} + +impl PyOrder { + pub(crate) fn new(order: Order) -> Self { + Self { order } + } +} + +#[pymethods] +impl PyOrder { + /// Constructor. + /// + /// Parameters + /// ---------- + /// alphas : int + /// power of :math:`\alpha_s` + /// alpha : int + /// power of :math:`\alpha` + /// logxir : int + /// power of :math:`\ln(\xi_r)` + /// logxif : int + /// power of :math:`\ln(\xi_f)` + #[new] + pub fn new_order(alphas: u32, alpha: u32, logxir: u32, logxif: u32) -> Self { + Self::new(Order::new(alphas, alpha, logxir, logxif)) + } + + /// Tuple representation. + /// + /// Returns + /// ------- + /// alphas : int + /// power of :math:`\alpha_s` + /// alpha : int + /// power of :math:`\alpha` + /// logxir : int + /// power of :math:`\ln(\xi_r)` + /// logxif : int + /// power of :math:`\ln(\xi_f)` + pub fn as_tuple(&self) -> (u32, u32, u32, u32) { + ( + self.order.alphas, + self.order.alpha, + self.order.logxir, + self.order.logxif, + ) + } + + /// Return a mask suitable to pass as the `order_mask` parameter of [`Grid::convolve`]. + /// + /// The selection of `orders` is controlled using the `max_as` and `max_al` parameters, for + /// instance setting `max_as = 1` and `max_al = 0` selects the LO QCD only, `max_as = 2` and + /// `max_al = 0` the NLO QCD; setting `max_as = 3` and `max_al = 2` would select all NLOs, and + /// the NNLO QCD. + /// + /// See `pineappl` crate docs for more examples. + /// + /// Returns + /// ------- + /// numpy.ndarray(bool) + /// boolean array, to be used as orders' mask + #[staticmethod] + pub fn create_mask<'py>( + orders: Vec>, + max_as: u32, + max_al: u32, + logs: bool, + py: Python<'py>, + ) -> Bound<'py, PyArray1> { + Order::create_mask( + &orders.iter().map(|o| o.order.clone()).collect::>(), + max_as, + max_al, + logs, + ) + .into_pyarray_bound(py) + } +} diff --git a/pineappl_py/src/channel.rs b/pineappl_py/src/channel.rs deleted file mode 100644 index 3f257430a..000000000 --- a/pineappl_py/src/channel.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Channel interface. -use pineappl::boc::Channel; - -use pyo3::prelude::*; - -/// PyO3 wrapper to :rustdoc:`pineappl::boc::Channel `. -/// -/// Each entry consists of a tuple, which contains, in the following order: -/// -/// 1. the PDG id of the first incoming parton -/// 2. the PDG id of the second parton -/// 3. a numerical factor that will multiply the result for this specific combination. -#[pyclass(name = "Channel")] -#[repr(transparent)] -pub struct PyChannel { - pub(crate) entry: Channel, -} - -impl PyChannel { - pub(crate) fn new(entry: Channel) -> Self { - Self { entry } - } -} - -#[pymethods] -impl PyChannel { - /// Constructor. - /// - /// Parameters - /// ---------- - /// entry: list(tuple(int, int, float)) - /// channel configuration - #[new] - pub fn new_entry(entry: Vec<(i32, i32, f64)>) -> Self { - Self::new(Channel::new(entry)) - } - - /// Get list representation. - /// - /// Returns - /// ------- - /// list(tuple(int,int,float)) : - /// list representation - pub fn into_array(&self) -> Vec<(i32, i32, f64)> { - self.entry.entry().to_vec() - } -} - -/// Register submodule in parent. -pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { - let m = PyModule::new_bound(parent_module.py(), "channel")?; - m.setattr(pyo3::intern!(m.py(), "__doc__"), "Channel interface.")?; - pyo3::py_run!( - parent_module.py(), - m, - "import sys; sys.modules['pineappl.channel'] = m" - ); - m.add_class::()?; - parent_module.add_submodule(&m) -} diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index 2835e8cf9..28d1b8bd8 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -1,29 +1,11 @@ //! Evolution interface. + +use super::pids::PyPidBasis; use numpy::{IntoPyArray, PyArray1}; use pineappl::evolution::{EvolveInfo, OperatorSliceInfo}; -use pineappl::pids::PidBasis; use pyo3::prelude::*; -/// PyO3 wrapper to :rustdoc:`pineappl::pids::PidBasis `. -#[pyclass(name = "PidBasis")] -#[derive(Clone)] -pub enum PyPidBasis { - /// PDG Monte Carlo IDs. - Pdg, - /// NNPDF's evolution basis IDs. - Evol, -} - -impl From for PidBasis { - fn from(basis: PyPidBasis) -> Self { - match basis { - PyPidBasis::Pdg => Self::Pdg, - PyPidBasis::Evol => Self::Evol, - } - } -} - /// PyO3 wrapper to :rustdoc:`pineappl::evolution::OperatorSliceInfo `. #[pyclass(name = "OperatorSliceInfo")] #[derive(Clone)] @@ -120,6 +102,5 @@ pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { ); m.add_class::()?; m.add_class::()?; - m.add_class::()?; parent_module.add_submodule(&m) } diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 2c485a5b6..998cd7290 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -1,12 +1,11 @@ //! Grid interface. use ndarray::CowArray; -use pineappl::boc::Order; use pineappl::convolutions::LumiCache; use pineappl::evolution::AlphasTable; use pineappl::grid::{Grid, Ntuple}; use super::bin::PyBinRemapper; -use super::channel::PyChannel; +use super::boc::{PyChannel, PyOrder}; use super::evolution::{PyEvolveInfo, PyOperatorSliceInfo}; use super::fk_table::PyFkTable; use super::subgrid::{PySubgridEnum, PySubgridParams}; @@ -23,90 +22,6 @@ use pyo3::exceptions::PyValueError; use pyo3::prelude::*; use pyo3::types::PyIterator; -/// PyO3 wrapper to :rustdoc:`pineappl::boc::Order `. -#[pyclass(name = "Order")] -#[repr(transparent)] -pub struct PyOrder { - pub(crate) order: Order, -} - -impl PyOrder { - pub(crate) fn new(order: Order) -> Self { - Self { order } - } -} - -#[pymethods] -impl PyOrder { - /// Constructor. - /// - /// Parameters - /// ---------- - /// alphas : int - /// power of :math:`\alpha_s` - /// alpha : int - /// power of :math:`\alpha` - /// logxir : int - /// power of :math:`\ln(\xi_r)` - /// logxif : int - /// power of :math:`\ln(\xi_f)` - #[new] - pub fn new_order(alphas: u32, alpha: u32, logxir: u32, logxif: u32) -> Self { - Self::new(Order::new(alphas, alpha, logxir, logxif)) - } - - /// Tuple representation. - /// - /// Returns - /// ------- - /// alphas : int - /// power of :math:`\alpha_s` - /// alpha : int - /// power of :math:`\alpha` - /// logxir : int - /// power of :math:`\ln(\xi_r)` - /// logxif : int - /// power of :math:`\ln(\xi_f)` - pub fn as_tuple(&self) -> (u32, u32, u32, u32) { - ( - self.order.alphas, - self.order.alpha, - self.order.logxir, - self.order.logxif, - ) - } - - /// Return a mask suitable to pass as the `order_mask` parameter of [`Grid::convolve`]. - /// - /// The selection of `orders` is controlled using the `max_as` and `max_al` parameters, for - /// instance setting `max_as = 1` and `max_al = 0` selects the LO QCD only, `max_as = 2` and - /// `max_al = 0` the NLO QCD; setting `max_as = 3` and `max_al = 2` would select all NLOs, and - /// the NNLO QCD. - /// - /// See `pineappl` crate docs for more examples. - /// - /// Returns - /// ------- - /// numpy.ndarray(bool) - /// boolean array, to be used as orders' mask - #[staticmethod] - pub fn create_mask<'py>( - orders: Vec>, - max_as: u32, - max_al: u32, - logs: bool, - py: Python<'py>, - ) -> Bound<'py, PyArray1> { - Order::create_mask( - &orders.iter().map(|o| o.order.clone()).collect::>(), - max_as, - max_al, - logs, - ) - .into_pyarray_bound(py) - } -} - /// PyO3 wrapper to :rustdoc:`pineappl::grid::Grid `. #[pyclass(name = "Grid")] #[repr(transparent)] diff --git a/pineappl_py/src/lib.rs b/pineappl_py/src/lib.rs index 458382aa8..0f10ee9b1 100644 --- a/pineappl_py/src/lib.rs +++ b/pineappl_py/src/lib.rs @@ -4,11 +4,12 @@ use pyo3::prelude::*; pub mod bin; -pub mod channel; +pub mod boc; pub mod evolution; pub mod fk_table; pub mod grid; pub mod import_only_subgrid; +pub mod pids; pub mod subgrid; /// PyO3 Python module that contains all exposed classes from Rust. @@ -17,11 +18,12 @@ pub mod subgrid; #[pymodule] fn pineappl(m: &Bound<'_, PyModule>) -> PyResult<()> { bin::register(m)?; + boc::register(m)?; grid::register(m)?; import_only_subgrid::register(m)?; evolution::register(m)?; - channel::register(m)?; fk_table::register(m)?; + pids::register(m)?; subgrid::register(m)?; m.add("version", env!("CARGO_PKG_VERSION"))?; diff --git a/pineappl_py/tests/test_boc.py b/pineappl_py/tests/test_boc.py new file mode 100644 index 000000000..9b00171d5 --- /dev/null +++ b/pineappl_py/tests/test_boc.py @@ -0,0 +1,7 @@ +import pineappl + + +class TestChannel: + def test_init(self): + le = pineappl.boc.Channel([(2, 2, 0.5)]) + assert isinstance(le, pineappl.boc.Channel) diff --git a/pineappl_py/tests/test_channel.py b/pineappl_py/tests/test_channel.py deleted file mode 100644 index fd07df6b6..000000000 --- a/pineappl_py/tests/test_channel.py +++ /dev/null @@ -1,7 +0,0 @@ -import pineappl - - -class TestChannel: - def test_init(self): - le = pineappl.channel.Channel([(2, 2, 0.5)]) - assert isinstance(le, pineappl.channel.Channel) diff --git a/pineappl_py/tests/test_fk_table.py b/pineappl_py/tests/test_fk_table.py index 97237c745..af047ed8d 100644 --- a/pineappl_py/tests/test_fk_table.py +++ b/pineappl_py/tests/test_fk_table.py @@ -5,7 +5,7 @@ class TestFkTable: def fake_grid(self, bins=None): - channels = [pineappl.channel.Channel([(1, 21, 1.0)])] + channels = [pineappl.boc.Channel([(1, 21, 1.0)])] orders = [pineappl.grid.Order(0, 0, 0, 0)] bin_limits = np.array([1e-7, 1e-3, 1] if bins is None else bins, dtype=float) subgrid_params = pineappl.subgrid.SubgridParams() @@ -36,7 +36,7 @@ def test_convolve_with_one(self): ) info = pineappl.evolution.OperatorSliceInfo( - 1.0, [], [], 1.0, [], [], pineappl.evolution.PidBasis.Pdg + 1.0, [], [], 1.0, [], [], pineappl.pids.PidBasis.Pdg ) # TODO: write a better test diff --git a/pineappl_py/tests/test_grid.py b/pineappl_py/tests/test_grid.py index 8a60a068e..f0678db99 100644 --- a/pineappl_py/tests/test_grid.py +++ b/pineappl_py/tests/test_grid.py @@ -15,7 +15,7 @@ def test_init(self): class TestGrid: def fake_grid(self, bins=None): - channels = [pineappl.channel.Channel([(1, 21, 0.1)])] + channels = [pineappl.boc.Channel([(1, 21, 0.1)])] orders = [pineappl.grid.Order(3, 0, 0, 0)] bin_limits = np.array([1e-7, 1e-3, 1] if bins is None else bins, dtype=float) subgrid_params = pineappl.subgrid.SubgridParams() diff --git a/pineappl_py/tests/test_sugrid.py b/pineappl_py/tests/test_sugrid.py index f4fedff2f..91a0d423b 100644 --- a/pineappl_py/tests/test_sugrid.py +++ b/pineappl_py/tests/test_sugrid.py @@ -11,7 +11,7 @@ def test_init(self): def test_issue_164(pdf): - channels = [pineappl.channel.Channel([(1, 2, 1.0)])] + channels = [pineappl.boc.Channel([(1, 2, 1.0)])] orders = [pineappl.grid.Order(0, 0, 0, 0)] params = pineappl.subgrid.SubgridParams() @@ -33,7 +33,7 @@ def convolve_grid(): class TestSubgrid: def fake_grid(self): - channels = [pineappl.channel.Channel([(1, 2, 1.0)])] + channels = [pineappl.boc.Channel([(1, 2, 1.0)])] orders = [pineappl.grid.Order(0, 0, 0, 0)] params = pineappl.subgrid.SubgridParams() bin_limits = np.array([0.0, 1.0]) From e3174cbce50eebcebf764e2ebb6c548f8c6ada79 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:33:51 +0200 Subject: [PATCH 45/51] Remove comment --- pineappl_py/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pineappl_py/src/lib.rs b/pineappl_py/src/lib.rs index 0f10ee9b1..e6bf31851 100644 --- a/pineappl_py/src/lib.rs +++ b/pineappl_py/src/lib.rs @@ -13,8 +13,6 @@ pub mod pids; pub mod subgrid; /// PyO3 Python module that contains all exposed classes from Rust. -/// -/// NOTE: this name has to match the one in Cargo.toml 'lib.name' #[pymodule] fn pineappl(m: &Bound<'_, PyModule>) -> PyResult<()> { bin::register(m)?; From 803c460fbc6c469e1095c8db5afbcfaf2fd27ddd Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:38:35 +0200 Subject: [PATCH 46/51] Add missing file `pineappl_py/src/pids.rs` --- pineappl_py/src/pids.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 pineappl_py/src/pids.rs diff --git a/pineappl_py/src/pids.rs b/pineappl_py/src/pids.rs new file mode 100644 index 000000000..81b3b67e4 --- /dev/null +++ b/pineappl_py/src/pids.rs @@ -0,0 +1,36 @@ +//! PIDs interface. + +use pineappl::pids::PidBasis; +use pyo3::prelude::*; + +/// PyO3 wrapper to :rustdoc:`pineappl::pids::PidBasis `. +#[pyclass(name = "PidBasis")] +#[derive(Clone)] +pub enum PyPidBasis { + /// PDG Monte Carlo IDs. + Pdg, + /// NNPDF's evolution basis IDs. + Evol, +} + +impl From for PidBasis { + fn from(basis: PyPidBasis) -> Self { + match basis { + PyPidBasis::Pdg => Self::Pdg, + PyPidBasis::Evol => Self::Evol, + } + } +} + +/// Register submodule in parent. +pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { + let m = PyModule::new_bound(parent_module.py(), "pids")?; + m.setattr(pyo3::intern!(m.py(), "__doc__"), "PIDs interface.")?; + pyo3::py_run!( + parent_module.py(), + m, + "import sys; sys.modules['pineappl.pids'] = m" + ); + m.add_class::()?; + parent_module.add_submodule(&m) +} From 011125b8509c5a4d3f8d61bae7b64fe9f9f608b9 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:58:41 +0200 Subject: [PATCH 47/51] Remove boilerplate code --- pineappl_py/src/bin.rs | 12 ++++-------- pineappl_py/src/boc.rs | 12 ++++-------- pineappl_py/src/grid.rs | 24 +++++++++++------------- pineappl_py/src/subgrid.rs | 12 +++--------- 4 files changed, 22 insertions(+), 38 deletions(-) diff --git a/pineappl_py/src/bin.rs b/pineappl_py/src/bin.rs index 445b9428f..76cd5b47e 100644 --- a/pineappl_py/src/bin.rs +++ b/pineappl_py/src/bin.rs @@ -12,12 +12,6 @@ pub struct PyBinRemapper { pub(crate) bin_remapper: BinRemapper, } -impl PyBinRemapper { - pub(crate) fn new(bin_remapper: BinRemapper) -> Self { - Self { bin_remapper } - } -} - #[pymethods] impl PyBinRemapper { /// Constructor. @@ -29,8 +23,10 @@ impl PyBinRemapper { /// limits : list(tuple(float, float)) /// bin limits #[new] - pub fn new_f64(normalizations: PyReadonlyArray1, limits: Vec<(f64, f64)>) -> Self { - Self::new(BinRemapper::new(normalizations.to_vec().unwrap(), limits).unwrap()) + pub fn new(normalizations: PyReadonlyArray1, limits: Vec<(f64, f64)>) -> Self { + Self { + bin_remapper: BinRemapper::new(normalizations.to_vec().unwrap(), limits).unwrap(), + } } } diff --git a/pineappl_py/src/boc.rs b/pineappl_py/src/boc.rs index aadad4611..124bd0c00 100644 --- a/pineappl_py/src/boc.rs +++ b/pineappl_py/src/boc.rs @@ -18,12 +18,6 @@ pub struct PyChannel { pub(crate) entry: Channel, } -impl PyChannel { - pub(crate) fn new(entry: Channel) -> Self { - Self { entry } - } -} - #[pymethods] impl PyChannel { /// Constructor. @@ -33,8 +27,10 @@ impl PyChannel { /// entry: list(tuple(int, int, float)) /// channel configuration #[new] - pub fn new_entry(entry: Vec<(i32, i32, f64)>) -> Self { - Self::new(Channel::new(entry)) + pub fn new(entry: Vec<(i32, i32, f64)>) -> Self { + Self { + entry: Channel::new(entry), + } } /// Get list representation. diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 998cd7290..98314b07b 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -30,12 +30,6 @@ pub struct PyGrid { pub(crate) grid: Grid, } -impl PyGrid { - pub(crate) fn new(grid: Grid) -> Self { - Self { grid } - } -} - #[pymethods] impl PyGrid { /// Constructor. @@ -57,12 +51,14 @@ impl PyGrid { bin_limits: PyReadonlyArray1, subgrid_params: PySubgridParams, ) -> Self { - Self::new(Grid::new( - channels.iter().map(|pyc| pyc.entry.clone()).collect(), - orders.iter().map(|pyo| pyo.order.clone()).collect(), - bin_limits.to_vec().unwrap(), - subgrid_params.subgrid_params, - )) + Self { + grid: Grid::new( + channels.iter().map(|pyc| pyc.entry.clone()).collect(), + orders.iter().map(|pyo| pyo.order.clone()).collect(), + bin_limits.to_vec().unwrap(), + subgrid_params.subgrid_params, + ), + } } /// Add a point to the grid. @@ -508,7 +504,9 @@ impl PyGrid { /// grid #[staticmethod] pub fn read(path: PathBuf) -> Self { - Self::new(Grid::read(BufReader::new(File::open(path).unwrap())).unwrap()) + Self { + grid: Grid::read(BufReader::new(File::open(path).unwrap())).unwrap(), + } } /// Write to file. diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index 13dda42b0..d02909613 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -12,12 +12,6 @@ pub struct PySubgridParams { pub(crate) subgrid_params: SubgridParams, } -impl PySubgridParams { - pub(crate) fn new(subgrid_params: SubgridParams) -> Self { - Self { subgrid_params } - } -} - impl Clone for PySubgridParams { fn clone(&self) -> Self { let mut subgrid_params = SubgridParams::default(); @@ -39,9 +33,9 @@ impl PySubgridParams { /// Constructor using the defaults. #[new] pub fn default() -> Self { - let subgrid_params = SubgridParams::default(); - - Self::new(subgrid_params) + Self { + subgrid_params: SubgridParams::default(), + } } /// Set number of :math:`Q^2` bins. From 5e730567d6a6677d3c82cd103262612cc7fc8d37 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 09:59:43 +0200 Subject: [PATCH 48/51] Reorder use statements --- pineappl_py/src/bin.rs | 2 +- pineappl_py/src/boc.rs | 1 - pineappl_py/src/evolution.rs | 1 - pineappl_py/src/fk_table.rs | 8 +++----- pineappl_py/src/grid.rs | 17 +++++++---------- pineappl_py/src/import_only_subgrid.rs | 2 +- pineappl_py/src/lib.rs | 1 + pineappl_py/src/subgrid.rs | 1 + 8 files changed, 14 insertions(+), 19 deletions(-) diff --git a/pineappl_py/src/bin.rs b/pineappl_py/src/bin.rs index 76cd5b47e..17398e175 100644 --- a/pineappl_py/src/bin.rs +++ b/pineappl_py/src/bin.rs @@ -1,7 +1,7 @@ //! Binnning interface. -use pineappl::bin::BinRemapper; use numpy::{PyArrayMethods, PyReadonlyArray1}; +use pineappl::bin::BinRemapper; use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::bin::BinRemapper `. diff --git a/pineappl_py/src/boc.rs b/pineappl_py/src/boc.rs index 124bd0c00..343aa71bb 100644 --- a/pineappl_py/src/boc.rs +++ b/pineappl_py/src/boc.rs @@ -2,7 +2,6 @@ use numpy::{IntoPyArray, PyArray1}; use pineappl::boc::{Channel, Order}; - use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::boc::Channel `. diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index 28d1b8bd8..762ee7e20 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -3,7 +3,6 @@ use super::pids::PyPidBasis; use numpy::{IntoPyArray, PyArray1}; use pineappl::evolution::{EvolveInfo, OperatorSliceInfo}; - use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::evolution::OperatorSliceInfo `. diff --git a/pineappl_py/src/fk_table.rs b/pineappl_py/src/fk_table.rs index 08328dcd7..33af7ffe7 100644 --- a/pineappl_py/src/fk_table.rs +++ b/pineappl_py/src/fk_table.rs @@ -1,19 +1,17 @@ //! FK table interface. + +use super::grid::PyGrid; +use numpy::{IntoPyArray, PyArray1, PyArray4, PyArrayMethods, PyReadonlyArray1}; use pineappl::convolutions::LumiCache; use pineappl::fk_table::{FkAssumptions, FkTable}; use pineappl::grid::Grid; - -use numpy::{IntoPyArray, PyArray1, PyArray4, PyArrayMethods, PyReadonlyArray1}; use pyo3::prelude::*; - use std::collections::HashMap; use std::fs::File; use std::io::BufReader; use std::path::PathBuf; use std::str::FromStr; -use crate::grid::PyGrid; - /// PyO3 wrapper to :rustdoc:`pineappl::fk_table::FkTable `. #[pyclass(name = "FkTable")] #[repr(transparent)] diff --git a/pineappl_py/src/grid.rs b/pineappl_py/src/grid.rs index 98314b07b..dbca4db7d 100644 --- a/pineappl_py/src/grid.rs +++ b/pineappl_py/src/grid.rs @@ -1,27 +1,24 @@ //! Grid interface. -use ndarray::CowArray; -use pineappl::convolutions::LumiCache; -use pineappl::evolution::AlphasTable; -use pineappl::grid::{Grid, Ntuple}; use super::bin::PyBinRemapper; use super::boc::{PyChannel, PyOrder}; use super::evolution::{PyEvolveInfo, PyOperatorSliceInfo}; use super::fk_table::PyFkTable; use super::subgrid::{PySubgridEnum, PySubgridParams}; - use itertools::izip; +use ndarray::CowArray; use numpy::{IntoPyArray, PyArray1, PyArrayMethods, PyReadonlyArray1, PyReadonlyArray4}; - +use pineappl::convolutions::LumiCache; +use pineappl::evolution::AlphasTable; +use pineappl::grid::{Grid, Ntuple}; +use pyo3::exceptions::PyValueError; +use pyo3::prelude::*; +use pyo3::types::PyIterator; use std::collections::HashMap; use std::fs::File; use std::io::BufReader; use std::path::PathBuf; -use pyo3::exceptions::PyValueError; -use pyo3::prelude::*; -use pyo3::types::PyIterator; - /// PyO3 wrapper to :rustdoc:`pineappl::grid::Grid `. #[pyclass(name = "Grid")] #[repr(transparent)] diff --git a/pineappl_py/src/import_only_subgrid.rs b/pineappl_py/src/import_only_subgrid.rs index fa52b132d..b58a006cc 100644 --- a/pineappl_py/src/import_only_subgrid.rs +++ b/pineappl_py/src/import_only_subgrid.rs @@ -1,6 +1,6 @@ //! PyImportOnlySubgrid* interface. -use super::subgrid::PySubgridEnum; +use super::subgrid::PySubgridEnum; use numpy::{PyArrayMethods, PyReadonlyArray1, PyReadonlyArray3}; use pineappl::import_only_subgrid::ImportOnlySubgridV1; use pineappl::import_only_subgrid::ImportOnlySubgridV2; diff --git a/pineappl_py/src/lib.rs b/pineappl_py/src/lib.rs index e6bf31851..5c0c5e1d2 100644 --- a/pineappl_py/src/lib.rs +++ b/pineappl_py/src/lib.rs @@ -1,4 +1,5 @@ //! Generate PyO3 interface. + #![allow(unsafe_op_in_unsafe_fn)] use pyo3::prelude::*; diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index d02909613..06e82eb2a 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -1,4 +1,5 @@ //! Subgrid interface. + use ndarray::Array3; use numpy::{IntoPyArray, PyArray1, PyArray3}; use pineappl::subgrid::Mu2; From ad4395159c17056e53ca51bbd0764d62ce40282c Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 10:01:31 +0200 Subject: [PATCH 49/51] Add missing `repr(transparent)` --- pineappl_py/src/evolution.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pineappl_py/src/evolution.rs b/pineappl_py/src/evolution.rs index 762ee7e20..4a28a3de6 100644 --- a/pineappl_py/src/evolution.rs +++ b/pineappl_py/src/evolution.rs @@ -8,6 +8,7 @@ use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::evolution::OperatorSliceInfo `. #[pyclass(name = "OperatorSliceInfo")] #[derive(Clone)] +#[repr(transparent)] pub struct PyOperatorSliceInfo { pub(crate) info: OperatorSliceInfo, } From 8ef229741373a9a49fb67883f69e228de8d5a66d Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 10:03:28 +0200 Subject: [PATCH 50/51] Fix bug in `PySubgridParams::clone` --- pineappl_py/src/subgrid.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/pineappl_py/src/subgrid.rs b/pineappl_py/src/subgrid.rs index 06e82eb2a..5eb89a78a 100644 --- a/pineappl_py/src/subgrid.rs +++ b/pineappl_py/src/subgrid.rs @@ -8,27 +8,12 @@ use pyo3::prelude::*; /// PyO3 wrapper to :rustdoc:`pineappl::subgrid::SubgridParams ` #[pyclass(name = "SubgridParams")] +#[derive(Clone)] #[repr(transparent)] pub struct PySubgridParams { pub(crate) subgrid_params: SubgridParams, } -impl Clone for PySubgridParams { - fn clone(&self) -> Self { - let mut subgrid_params = SubgridParams::default(); - subgrid_params.set_q2_bins(self.subgrid_params.q2_bins()); - subgrid_params.set_q2_max(self.subgrid_params.q2_max()); - subgrid_params.set_q2_min(self.subgrid_params.q2_min()); - subgrid_params.set_q2_order(self.subgrid_params.q2_order()); - subgrid_params.set_reweight(self.subgrid_params.reweight()); - subgrid_params.set_x_bins(self.subgrid_params.x_bins()); - subgrid_params.set_x_max(self.subgrid_params.x_max()); - subgrid_params.set_x_min(self.subgrid_params.x_min()); - subgrid_params.set_x_order(self.subgrid_params.x_order()); - Self { subgrid_params } - } -} - #[pymethods] impl PySubgridParams { /// Constructor using the defaults. From 73868e969f778e19357ee4be09325b6562ac7db0 Mon Sep 17 00:00:00 2001 From: Christopher Schwan Date: Thu, 15 Aug 2024 11:08:09 +0200 Subject: [PATCH 51/51] Fix `CHANGELOG.md` Co-authored-by: Felix Hekhorn --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 538f63d42..c244fc1ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Python API: dropped top-level Python interface layer - Python API: renamed `lumi` to `channel` in PyO3 Python interface. This concerns 1) the argument names of `convolute_with_one` and similar functions; - 2) the module `pineappl.lumi` was moved to `pineappl.channel`; 3) the class + 2) the module `pineappl.lumi` was moved to `pineappl.boc`; 3) the class `LumiEntry` was renamed to `Channel` - Python API: `.into()` needs to be explicitly called on subgrids when calling `pineappl.grid.set_subgrid()`