From cda1b1c6d4925c9b1c8036ed677f8558e924a684 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Tue, 22 Jul 2025 17:46:42 +0200 Subject: [PATCH 1/4] Extend to include Physical Parameters --- neopdf/src/metadata.rs | 33 ++++ neopdf/src/writer.rs | 15 +- neopdf_capi/src/include/NeoPDF.hpp | 34 ++++ neopdf_capi/src/lib.rs | 50 ++++- neopdf_capi/tests/check-oop.cpp | 9 - neopdf_capi/tests/check-writer-oop.cpp | 103 ++++------- neopdf_capi/tests/check-writer.cpp | 15 ++ neopdf_pyapi/src/metadata.rs | 245 ++++++++++++++----------- 8 files changed, 313 insertions(+), 191 deletions(-) diff --git a/neopdf/src/metadata.rs b/neopdf/src/metadata.rs index 6d47f0f3..f0aa0c90 100644 --- a/neopdf/src/metadata.rs +++ b/neopdf/src/metadata.rs @@ -81,6 +81,39 @@ pub struct MetaData { /// The code version (CARGO_PKG_VERSION) that generated the PDF. #[serde(rename = "CodeVersion", default)] pub code_version: String, + /// Scheme for the treatment of heavy flavors + #[serde(rename = "FlavorScheme", default)] + pub flavor_scheme: String, + /// Number of QCD loops in the calculation of PDF evolution. + #[serde(rename = "OrderQCD", default)] + pub order_qcd: u32, + /// Number of QCD loops in the calculation of `alpha_s`. + #[serde(rename = "AlphaS OrderQCD", default)] + pub alphas_order_qcd: u32, + /// Value of the W boson mass. + #[serde(rename = "MW", default)] + pub m_w: f64, + /// Value of the Z boson mass. + #[serde(rename = "MZ", default)] + pub m_z: f64, + /// Value of the Up quark mass. + #[serde(rename = "MUp", default)] + pub m_up: f64, + /// Value of the Down quark mass. + #[serde(rename = "MDown", default)] + pub m_down: f64, + /// Value of the Strange quark mass. + #[serde(rename = "MStrange", default)] + pub m_strange: f64, + /// Value of the Charm quark mass. + #[serde(rename = "MCharm", default)] + pub m_charm: f64, + /// Value of the Bottom quark mass. + #[serde(rename = "MBottom", default)] + pub m_bottom: f64, + /// Value of the Top quark mass. + #[serde(rename = "MTop", default)] + pub m_top: f64, } impl fmt::Display for MetaData { diff --git a/neopdf/src/writer.rs b/neopdf/src/writer.rs index af0260d5..6ee2c971 100644 --- a/neopdf/src/writer.rs +++ b/neopdf/src/writer.rs @@ -457,8 +457,19 @@ mod tests { interpolator_type: InterpolatorType::LogBicubic, error_type: "replicas".into(), hadron_pid: 2212, - git_version: "".into(), - code_version: "".into(), + git_version: String::new(), + code_version: String::new(), + flavor_scheme: String::new(), + order_qcd: 0, + alphas_order_qcd: 0, + m_w: 0.0, + m_z: 0.0, + m_up: 0.0, + m_down: 0.0, + m_strange: 0.0, + m_charm: 0.0, + m_bottom: 0.0, + m_top: 0.0, }; let test_grid = test_grid(); diff --git a/neopdf_capi/src/include/NeoPDF.hpp b/neopdf_capi/src/include/NeoPDF.hpp index 011f61e4..c31bfd9d 100644 --- a/neopdf_capi/src/include/NeoPDF.hpp +++ b/neopdf_capi/src/include/NeoPDF.hpp @@ -12,6 +12,38 @@ /** @brief Object Oriented interface to NeoPDF. */ namespace neopdf { +/** @brief C++ representation of PhysicsParameters. */ +struct PhysicsParameters { + std::string flavor_scheme; + uint32_t order_qcd; + uint32_t alphas_order_qcd; + double m_w; + double m_z; + double m_up; + double m_down; + double m_strange; + double m_charm; + double m_bottom; + double m_top; + + // Conversion to C struct + NeoPDFPhysicsParameters to_c() const { + NeoPDFPhysicsParameters c_params; + c_params.flavor_scheme = flavor_scheme.c_str(); + c_params.order_qcd = order_qcd; + c_params.alphas_order_qcd = alphas_order_qcd; + c_params.m_w = m_w; + c_params.m_z = m_z; + c_params.m_up = m_up; + c_params.m_down = m_down; + c_params.m_strange = m_strange; + c_params.m_charm = m_charm; + c_params.m_bottom = m_bottom; + c_params.m_top = m_top; + return c_params; + } +}; + /** @brief C++ representation of NeoPDFMetaData. */ struct MetaData { std::string set_desc; @@ -30,6 +62,7 @@ struct MetaData { InterpolatorType interpolator_type; std::string error_type; int32_t hadron_pid; + PhysicsParameters phys_params; // Conversion to C struct NeoPDFMetaData to_c() const { @@ -53,6 +86,7 @@ struct MetaData { c_meta.interpolator_type = interpolator_type; c_meta.error_type = error_type.c_str(); c_meta.hadron_pid = hadron_pid; + c_meta.phys_params = phys_params.to_c(); return c_meta; } }; diff --git a/neopdf_capi/src/lib.rs b/neopdf_capi/src/lib.rs index 96d5f113..271a8214 100644 --- a/neopdf_capi/src/lib.rs +++ b/neopdf_capi/src/lib.rs @@ -588,6 +588,33 @@ pub unsafe extern "C" fn neopdf_grid_free(grid: *mut NeoPDFGrid) { } } +/// Physical Parameters of the PDF set. +#[repr(C)] +pub struct NeoPDFPhysicsParameters { + /// The flavor scheme used for the PDF set. + pub flavor_scheme: *const c_char, + /// Number of QCD loops in the calculation of PDF evolution. + pub order_qcd: u32, + /// Number of QCD loops in the calculation of `alpha_s`. + pub alphas_order_qcd: u32, + /// Value of the W boson mass. + pub m_w: f64, + /// Value of the Z boson mass. + pub m_z: f64, + /// Value of the `u` quark mass. + pub m_up: f64, + /// Value of the `d` quark mass. + pub m_down: f64, + /// Value of the `s` quark mass. + pub m_strange: f64, + /// Value of the `c` quark mass. + pub m_charm: f64, + /// Value of the `b` quark mass. + pub m_bottom: f64, + /// Value of the `t` quark mass. + pub m_top: f64, +} + /// Metadata for PDF grids #[repr(C)] pub struct NeoPDFMetaData { @@ -610,6 +637,7 @@ pub struct NeoPDFMetaData { interpolator_type: InterpolatorType, error_type: *const c_char, hadron_pid: c_int, + phys_params: NeoPDFPhysicsParameters, } /// Safely converts C string to Rust string @@ -645,8 +673,9 @@ fn process_metadata(meta: *const NeoPDFMetaData) -> Option { let alphas_q_values = unsafe { carray_to_vec(meta.alphas_q_values, meta.num_alphas_q) }?; let alphas_vals = unsafe { carray_to_vec(meta.alphas_vals, meta.num_alphas_vals) }?; let error_type = unsafe { cstr_to_string(meta.error_type) }?; + let flavor_scheme = unsafe { cstr_to_string(meta.phys_params.flavor_scheme) }?; - Some(MetaData { + let metadata = MetaData { set_desc, set_index: meta.set_index, num_members: meta.num_members, @@ -663,9 +692,22 @@ fn process_metadata(meta: *const NeoPDFMetaData) -> Option { interpolator_type: meta.interpolator_type.clone(), error_type, hadron_pid: meta.hadron_pid, - git_version: "None".to_string(), // placeholder to be overwritten - code_version: "None".to_string(), // placeholder to be overwritten - }) + git_version: String::new(), // placeholder to be overwritten + code_version: String::new(), // placeholder to be overwritten + flavor_scheme, + order_qcd: meta.phys_params.order_qcd, + alphas_order_qcd: meta.phys_params.alphas_order_qcd, + m_w: meta.phys_params.m_w, + m_z: meta.phys_params.m_z, + m_up: meta.phys_params.m_up, + m_down: meta.phys_params.m_down, + m_strange: meta.phys_params.m_strange, + m_charm: meta.phys_params.m_charm, + m_bottom: meta.phys_params.m_bottom, + m_top: meta.phys_params.m_top, + }; + + Some(metadata) } /// Represents a dynamically-sized collection of `NeoPDFGrid` pointers. diff --git a/neopdf_capi/tests/check-oop.cpp b/neopdf_capi/tests/check-oop.cpp index 4a65d99e..de9a1070 100644 --- a/neopdf_capi/tests/check-oop.cpp +++ b/neopdf_capi/tests/check-oop.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -204,14 +203,6 @@ void test_all_pdf_members() { std::cout << "Relative Std Dev: " << std_dev / mean << "\n"; } -void test_raw_load_all() { - std::cout << "=== Test raw neopdf_pdf_load_all ===\n"; - NeoPDFMembers raw_pdfs = neopdf_pdf_load_all("NNPDF40_nnlo_as_01180"); - std::cout << "Loaded " << raw_pdfs.size << " PDF members (raw call)\n"; - neopdf_pdf_array_free(raw_pdfs); -} - - int main() { // Test the computation of the PDF interpolations test_xfxq2(); diff --git a/neopdf_capi/tests/check-writer-oop.cpp b/neopdf_capi/tests/check-writer-oop.cpp index 45f74d59..ae67af25 100644 --- a/neopdf_capi/tests/check-writer-oop.cpp +++ b/neopdf_capi/tests/check-writer-oop.cpp @@ -1,4 +1,3 @@ -#include "neopdf_capi.h" #include #include #include @@ -31,27 +30,16 @@ int main() { // Extract the number of subgrids std::size_t num_subgrids = ref_pdf.num_subgrids(); - // Create a collection - NeoPDFGridArrayCollection* collection = neopdf_gridarray_collection_new(); - if (!collection) { - std::cerr << "Failed to create grid array collection!\n"; - return 1; - } + // Create a grid writer + GridWriter writer; // For each member, build a grid for (size_t m = 0; m < neo_pdfs.size(); ++m) { NeoPDF& pdf = neo_pdfs[m]; - NeoPDFGrid* grid = neopdf_grid_new(); - - if (!grid) { - std::cerr << "Failed to create grid for member: " << m << "!\n"; - continue; - } - bool member_ok = true; // Loop over the Subgrids for (std::size_t subgrid_idx = 0; subgrid_idx != num_subgrids; subgrid_idx++) { - // Extract the parameter values of the given subgrid + // Extract the knot values of the parameters for the subgrid auto xs = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_MOMENTUM, subgrid_idx); auto q2s = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_SCALE, subgrid_idx); auto alphas = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_ALPHAS, subgrid_idx); @@ -70,53 +58,43 @@ int main() { } } - // Add subgrid - int add_subgrid =neopdf_grid_add_subgrid( - grid, - nucleons.data(), nucleons.size(), - alphas.data(), alphas.size(), - kts.data(), kts.size(), - xs.data(), xs.size(), - q2s.data(), q2s.size(), - grid_data.data(), grid_data.size() + // Add grid + writer.add_grid( + nucleons, + alphas, + kts, + xs, + q2s, + grid_data, + pids ); - if (add_subgrid != NEOPDF_RESULT_SUCCESS) { - std::cerr << "Failed to add subgrid for member: " << m << "!\n"; - neopdf_grid_free(grid); - member_ok = false; - break; - } - } - - if (!member_ok) continue; - - // Set flavor PIDs - int add_flavors = neopdf_grid_set_flavors(grid, pids.data(), pids.size()); - if (add_flavors != NEOPDF_RESULT_SUCCESS) { - std::cerr << "Failed to set flavors for member: " << m << "!\n"; - neopdf_grid_free(grid); - continue; - } - - // Add grid to collection - int add_grid = neopdf_gridarray_collection_add_grid(collection, grid); - if (add_grid != NEOPDF_RESULT_SUCCESS) { - std::cerr << "Failed to add grid to collection for member: " << m << "!\n"; - neopdf_grid_free(grid); - continue; } std::cout << "Added grid for member " << m << "\n"; } // Fill the running of alphas with some random values - double alphas_qs[] = {2.0}; - double alphas_vals[] = {0.118}; + std::vector alphas_qs = {2.0}; + std::vector alphas_vals = {0.118}; // Extract the ranges for the momentum x and scale Q2 auto x_range = ref_pdf.param_range(NEOPDF_SUBGRID_PARAMS_MOMENTUM); auto q2_range = ref_pdf.param_range(NEOPDF_SUBGRID_PARAMS_SCALE); - NeoPDFMetaData meta = { + PhysicsParameters phys_params = { + .flavor_scheme = "variable", + .order_qcd = 2, + .alphas_order_qcd = 2, + .m_w = 80.352, + .m_z = 91.1876, + .m_up = 0.0, + .m_down = 0.0, + .m_strange = 0.0, + .m_charm = 1.51, + .m_bottom = 4.92, + .m_top = 172.5, + }; + + MetaData meta = { .set_desc = "NNPDF40_nnlo_as_01180 collection", .set_index = 0, .num_members = (uint32_t)neo_pdfs.size(), @@ -124,18 +102,16 @@ int main() { .x_max = x_range[1], .q_min = sqrt(q2_range[0]), .q_max = sqrt(q2_range[1]), - .flavors = pids.data(), - .num_flavors = (size_t)pids.size(), + .flavors = pids, .format = "neopdf", .alphas_q_values = alphas_qs, - .num_alphas_q = 1, .alphas_vals = alphas_vals, - .num_alphas_vals = 1, .polarised = false, .set_type = SET_TYPE_SPACE_LIKE, .interpolator_type = INTERPOLATOR_TYPE_LOG_BICUBIC, .error_type = "replicas", .hadron_pid = 2212, + .phys_params = phys_params, }; // Check if `NEOPDF_DATA_PATH` is defined and store the Grid there. @@ -146,11 +122,12 @@ int main() { : filename; // Write the PDF Grid into disk - int result = neopdf_grid_compress(collection, &meta, output_path.c_str()); - if (result != 0) { - std::cerr << "Compression failed with code " << result << "\n"; - } else { - std::cout << "Compression succeeded!" << "\n"; + try { + writer.compress(meta, output_path); + std::cout << "Compression succeeded!\n"; + } catch (const std::runtime_error& err) { + std::cerr << "Compression failed: " << err.what() << "\n"; + return EXIT_FAILURE; } // If `NEOPDF_DATA_PATH` is defined, reload the grid and check ther results. @@ -171,9 +148,5 @@ int main() { assert(std::abs(res2 - ref2) < TOLERANCE); } - // Cleanup - neopdf_gridarray_collection_free(collection); - // The `neo_pdfs` object will be automatically destroyed, freeing the PDF members. - - return result == 0 ? 0 : 1; + return EXIT_SUCCESS; } diff --git a/neopdf_capi/tests/check-writer.cpp b/neopdf_capi/tests/check-writer.cpp index de406170..54fbad38 100644 --- a/neopdf_capi/tests/check-writer.cpp +++ b/neopdf_capi/tests/check-writer.cpp @@ -165,6 +165,20 @@ int main() { neopdf_pdf_param_range(neo_pdfs.pdfs[0], NEOPDF_SUBGRID_PARAMS_MOMENTUM, x_range.data()); neopdf_pdf_param_range(neo_pdfs.pdfs[0], NEOPDF_SUBGRID_PARAMS_SCALE, q2_range.data()); + NeoPDFPhysicsParameters phys_params = { + .flavor_scheme = "variable", + .order_qcd = 2, + .alphas_order_qcd = 2, + .m_w = 80.352, + .m_z = 91.1876, + .m_up = 0.0, + .m_down = 0.0, + .m_strange = 0.0, + .m_charm = 1.51, + .m_bottom = 4.92, + .m_top = 172.5, + }; + NeoPDFMetaData meta = { .set_desc = "NNPDF40_nnlo_as_01180 collection", .set_index = 0, @@ -185,6 +199,7 @@ int main() { .interpolator_type = INTERPOLATOR_TYPE_LOG_BICUBIC, .error_type = "replicas", .hadron_pid = 2212, + .phys_params = phys_params, }; // Check if `NEOPDF_DATA_PATH` is defined and store the Grid there. diff --git a/neopdf_pyapi/src/metadata.rs b/neopdf_pyapi/src/metadata.rs index 757b4056..2b772ba4 100644 --- a/neopdf_pyapi/src/metadata.rs +++ b/neopdf_pyapi/src/metadata.rs @@ -69,6 +69,111 @@ impl From<&PyInterpolatorType> for InterpolatorType { } } +/// Physical Parameters of the PDF set. +#[pyclass(name = "PhysicsParameters")] +#[derive(Debug, Clone)] +pub struct PyPhysicsParameters { + pub(crate) flavor_scheme: String, + pub(crate) order_qcd: u32, + pub(crate) alphas_order_qcd: u32, + pub(crate) m_w: f64, + pub(crate) m_z: f64, + pub(crate) m_up: f64, + pub(crate) m_down: f64, + pub(crate) m_strange: f64, + pub(crate) m_charm: f64, + pub(crate) m_bottom: f64, + pub(crate) m_top: f64, +} + +#[pymethods] +impl PyPhysicsParameters { + /// Constructor for PyPhysicsParameters. + #[new] + #[must_use] + #[allow(clippy::too_many_arguments)] + #[pyo3(signature = ( + flavor_scheme = "None".to_string(), + order_qcd = 0, + alphas_order_qcd = 0, + m_w = 0.0, + m_z = 0.0, + m_up = 0.0, + m_down = 0.0, + m_strange = 0.0, + m_charm = 0.0, + m_bottom = 0.0, + m_top = 0.0 + ))] + pub const fn new( + flavor_scheme: String, + order_qcd: u32, + alphas_order_qcd: u32, + m_w: f64, + m_z: f64, + m_up: f64, + m_down: f64, + m_strange: f64, + m_charm: f64, + m_bottom: f64, + m_top: f64, + ) -> Self { + Self { + flavor_scheme, + order_qcd, + alphas_order_qcd, + m_w, + m_z, + m_up, + m_down, + m_strange, + m_charm, + m_bottom, + m_top, + } + } + + /// Convert to Python dictionary. + /// + /// # Errors + /// + /// Raises an error if the values are not Python compatible. + pub fn to_dict(&self, py: Python) -> PyResult { + let dict = pyo3::types::PyDict::new(py); + dict.set_item("flavor_scheme", &self.flavor_scheme)?; + dict.set_item("order_qcd", self.order_qcd)?; + dict.set_item("alphas_order_qcd", self.alphas_order_qcd)?; + dict.set_item("m_w", self.m_w)?; + dict.set_item("m_z", self.m_z)?; + dict.set_item("m_up", self.m_up)?; + dict.set_item("m_down", self.m_down)?; + dict.set_item("m_strange", self.m_strange)?; + dict.set_item("m_charm", self.m_charm)?; + dict.set_item("m_bottom", self.m_bottom)?; + dict.set_item("m_top", self.m_top)?; + + Ok(dict.into()) + } +} + +impl Default for PyPhysicsParameters { + fn default() -> Self { + Self { + flavor_scheme: String::new(), + order_qcd: 0, + alphas_order_qcd: 0, + m_w: 0.0, + m_z: 0.0, + m_up: 0.0, + m_down: 0.0, + m_strange: 0.0, + m_charm: 0.0, + m_bottom: 0.0, + m_top: 0.0, + } + } +} + /// Grid metadata. #[pyclass(name = "MetaData")] #[derive(Debug, Clone)] @@ -100,7 +205,8 @@ impl PyMetaData { set_type = PySetType::SpaceLike, interpolator_type = PyInterpolatorType::LogBicubic, error_type = "replicas".to_string(), - hadron_pid = 2212 + hadron_pid = 2212, + phys_params = PyPhysicsParameters::default(), ))] pub fn new( set_desc: String, @@ -119,9 +225,11 @@ impl PyMetaData { interpolator_type: PyInterpolatorType, error_type: String, hadron_pid: i32, + phys_params: PyPhysicsParameters, ) -> Self { - let git_version = "Unknown".to_string(); - let code_version = "Unknown".to_string(); + let git_version = String::new(); + let code_version = String::new(); + let meta = MetaData { set_desc, set_index, @@ -141,6 +249,17 @@ impl PyMetaData { hadron_pid, git_version, // placeholder to be overwritten code_version, // placeholder to be overwritten + flavor_scheme: phys_params.flavor_scheme, + order_qcd: phys_params.order_qcd, + alphas_order_qcd: phys_params.alphas_order_qcd, + m_w: phys_params.m_w, + m_z: phys_params.m_z, + m_up: phys_params.m_up, + m_down: phys_params.m_down, + m_strange: phys_params.m_strange, + m_charm: phys_params.m_charm, + m_bottom: phys_params.m_bottom, + m_top: phys_params.m_top, }; Self { meta } @@ -185,117 +304,20 @@ impl PyMetaData { dict.set_item("hadron_pid", self.meta.hadron_pid)?; dict.set_item("git_version", &self.meta.git_version)?; dict.set_item("code_version", &self.meta.code_version)?; + dict.set_item("flavor_scheme", &self.meta.flavor_scheme)?; + dict.set_item("order_qcd", self.meta.order_qcd)?; + dict.set_item("alphas_order_qcd", self.meta.alphas_order_qcd)?; + dict.set_item("m_w", self.meta.m_w)?; + dict.set_item("m_z", self.meta.m_z)?; + dict.set_item("m_up", self.meta.m_up)?; + dict.set_item("m_down", self.meta.m_down)?; + dict.set_item("m_strange", self.meta.m_strange)?; + dict.set_item("m_charm", self.meta.m_charm)?; + dict.set_item("m_bottom", self.meta.m_bottom)?; + dict.set_item("m_top", self.meta.m_top)?; Ok(dict.into()) } - - /// The description of the grid. - #[must_use] - pub const fn description(&self) -> &String { - &self.meta.set_desc - } - - /// The index of the grid. - #[must_use] - pub const fn set_index(&self) -> u32 { - self.meta.set_index - } - - /// The number of sets in the grid. - #[must_use] - pub const fn number_sets(&self) -> u32 { - self.meta.num_members - } - - /// The minimum value of `x` in the grid. - #[must_use] - pub const fn x_min(&self) -> f64 { - self.meta.x_min - } - - /// The maximum value of `x` in the grid. - #[must_use] - pub const fn x_max(&self) -> f64 { - self.meta.x_max - } - - /// The minimum value of `q` in the grid. - #[must_use] - pub const fn q_min(&self) -> f64 { - self.meta.q_min - } - - /// The maximum value of `q` in the grid. - #[must_use] - pub const fn q_max(&self) -> f64 { - self.meta.q_max - } - - /// The particle IDs of the grid. - #[must_use] - pub const fn pids(&self) -> &Vec { - &self.meta.flavors - } - - /// The format of the grid. - #[must_use] - pub const fn format(&self) -> &String { - &self.meta.format - } - - /// The values of `q` for the running of the strong coupling constant. - #[must_use] - pub const fn alphas_q(&self) -> &Vec { - &self.meta.alphas_q_values - } - - /// The values of the running of the strong coupling constant. - #[must_use] - pub const fn alphas_values(&self) -> &Vec { - &self.meta.alphas_vals - } - - /// Whether the grid is polarised. - #[must_use] - pub const fn is_polarised(&self) -> bool { - self.meta.polarised - } - - /// The type of the set. - #[must_use] - pub fn set_type(&self) -> PySetType { - PySetType::from(&self.meta.set_type) - } - - /// The interpolation method used for the grid. - #[must_use] - pub fn interpolator_type(&self) -> PyInterpolatorType { - PyInterpolatorType::from(&self.meta.interpolator_type) - } - - /// The type of error. - #[must_use] - pub const fn error_type(&self) -> &String { - &self.meta.error_type - } - - /// The hadron PID. - #[must_use] - pub const fn hadron_pid(&self) -> i32 { - self.meta.hadron_pid - } - - /// The git version of the code that generated the PDF. - #[must_use] - pub const fn git_version(&self) -> &String { - &self.meta.git_version - } - - /// The code version (CARGO_PKG_VERSION) that generated the PDF. - #[must_use] - pub const fn code_version(&self) -> &String { - &self.meta.code_version - } } /// Registers the `metadata` submodule with the parent Python module. @@ -324,6 +346,7 @@ pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> { ); m.add_class::()?; m.add_class::()?; + m.add_class::()?; m.add_class::()?; parent_module.add_submodule(&m) } From 706123d11a6401035a8a35f0e8cd4f87ccef2ab4 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Tue, 22 Jul 2025 20:14:28 +0200 Subject: [PATCH 2/4] Fix Python API --- neopdf_pyapi/src/metadata.rs | 90 ++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/neopdf_pyapi/src/metadata.rs b/neopdf_pyapi/src/metadata.rs index 2b772ba4..301ff34e 100644 --- a/neopdf_pyapi/src/metadata.rs +++ b/neopdf_pyapi/src/metadata.rs @@ -318,6 +318,96 @@ impl PyMetaData { Ok(dict.into()) } + + /// The index of the grid. + #[must_use] + pub const fn set_index(&self) -> u32 { + self.meta.set_index + } + + /// The number of sets in the grid. + #[must_use] + pub const fn number_sets(&self) -> u32 { + self.meta.num_members + } + + /// The minimum value of `x` in the grid. + #[must_use] + pub const fn x_min(&self) -> f64 { + self.meta.x_min + } + + /// The maximum value of `x` in the grid. + #[must_use] + pub const fn x_max(&self) -> f64 { + self.meta.x_max + } + + /// The minimum value of `q` in the grid. + #[must_use] + pub const fn q_min(&self) -> f64 { + self.meta.q_min + } + + /// The maximum value of `q` in the grid. + #[must_use] + pub const fn q_max(&self) -> f64 { + self.meta.q_max + } + + /// The particle IDs of the grid. + #[must_use] + pub const fn pids(&self) -> &Vec { + &self.meta.flavors + } + + /// The format of the grid. + #[must_use] + pub const fn format(&self) -> &String { + &self.meta.format + } + + /// The values of `q` for the running of the strong coupling constant. + #[must_use] + pub const fn alphas_q(&self) -> &Vec { + &self.meta.alphas_q_values + } + + /// The values of the running of the strong coupling constant. + #[must_use] + pub const fn alphas_values(&self) -> &Vec { + &self.meta.alphas_vals + } + + /// Whether the grid is polarised. + #[must_use] + pub const fn is_polarised(&self) -> bool { + self.meta.polarised + } + + /// The type of the set. + #[must_use] + pub fn set_type(&self) -> PySetType { + PySetType::from(&self.meta.set_type) + } + + /// The interpolation method used for the grid. + #[must_use] + pub fn interpolator_type(&self) -> PyInterpolatorType { + PyInterpolatorType::from(&self.meta.interpolator_type) + } + + /// The type of error. + #[must_use] + pub const fn error_type(&self) -> &String { + &self.meta.error_type + } + + /// The hadron PID. + #[must_use] + pub const fn hadron_pid(&self) -> i32 { + self.meta.hadron_pid + } } /// Registers the `metadata` submodule with the parent Python module. From 0e787c4a463d77593b83d91b6b4f21edb55b0558 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Tue, 22 Jul 2025 21:09:32 +0200 Subject: [PATCH 3/4] Update the documentations accordingly --- docs/custom.css | 15 +++++ docs/examples/c-oop.md | 106 ++++++++++++------------------- docs/examples/c.md | 23 ++++++- docs/examples/neopdf-pyapi.ipynb | 103 +++++++++++++++++------------- 4 files changed, 136 insertions(+), 111 deletions(-) diff --git a/docs/custom.css b/docs/custom.css index 815a77a7..dc21582a 100644 --- a/docs/custom.css +++ b/docs/custom.css @@ -11,3 +11,18 @@ body { .md-content__inner li { text-align: justify; } + +/* Hide Jupyter input/output prompts in mkdocs-jupyter */ +.jp-InputPrompt, .jp-OutputPrompt, .prompt, .nbinput .prompt, .nboutput .prompt { + display: none !important; +} + +/* Slightly increase font size in notebook code cells for mkdocs-jupyter and similar renderers */ +div.nbinput .input_area pre, +div.input_area pre, +div.jp-InputArea-editor, +div.jp-CodeCell .jp-InputArea-editor, +div.highlight pre, +pre { + font-size: 1.06em !important; +} diff --git a/docs/examples/c-oop.md b/docs/examples/c-oop.md index 7f7ffa67..e9883e7f 100644 --- a/docs/examples/c-oop.md +++ b/docs/examples/c-oop.md @@ -281,8 +281,7 @@ below in the case the grid should explicitly depend on more parameters. is correct. However, this makes the codes very verbose. To easily spot the parts that actually fills the grid, some lines are highlighted. -```cpp linenums="1" hl_lines="62-70 73-81 93 101 118-138 148" -#include "neopdf_capi.h" +```cpp linenums="1" hl_lines="62-70 51-59 62-70 83-95 97-115 126" #include #include #include @@ -315,31 +314,21 @@ int main() { // Extract the number of subgrids std::size_t num_subgrids = ref_pdf.num_subgrids(); - // Create a collection - NeoPDFGridArrayCollection* collection = neopdf_gridarray_collection_new(); - if (!collection) { - std::cerr << "Failed to create grid array collection!\n"; - return 1; - } + // Create a grid writer + GridWriter writer; // For each member, build a grid for (size_t m = 0; m < neo_pdfs.size(); ++m) { NeoPDF& pdf = neo_pdfs[m]; - NeoPDFGrid* grid = neopdf_grid_new(); - - if (!grid) { - std::cerr << "Failed to create grid for member: " << m << "!\n"; - continue; - } - bool member_ok = true; // Loop over the Subgrids for (std::size_t subgrid_idx = 0; subgrid_idx != num_subgrids; subgrid_idx++) { - // Extract the parameter values of the given subgrid + // Extract the knot values of the parameters for the subgrid auto xs = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_MOMENTUM, subgrid_idx); auto q2s = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_SCALE, subgrid_idx); auto alphas = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_ALPHAS, subgrid_idx); auto nucleons = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_NUCLEONS, subgrid_idx); + auto kts = pdf.subgrid_for_param(NEOPDF_SUBGRID_PARAMS_KT, subgrid_idx); // Compute grid_data: [q2s][xs][flavors], instead of [nucleons][alphas][q2s][xs][flavors] // NOTE: This assumes that there is no 'A' and `alphas` dependence. @@ -353,53 +342,43 @@ int main() { } } - // Add subgrid - int add_subgrid =neopdf_grid_add_subgrid( - grid, - nucleons.data(), nucleons.size(), - alphas.data(), alphas.size(), - kts.data(), kts.size(), - xs.data(), xs.size(), - q2s.data(), q2s.size(), - grid_data.data(), grid_data.size() + // Add grid + writer.add_grid( + nucleons, + alphas, + kts, + xs, + q2s, + grid_data, + pids ); - if (add_subgrid != NEOPDF_RESULT_SUCCESS) { - std::cerr << "Failed to add subgrid for member: " << m << "!\n"; - neopdf_grid_free(grid); - member_ok = false; - break; - } - } - - if (!member_ok) continue; - - // Set flavor PIDs - int add_flavors = neopdf_grid_set_flavors(grid, pids.data(), pids.size()); - if (add_flavors != NEOPDF_RESULT_SUCCESS) { - std::cerr << "Failed to set flavors for member: " << m << "!\n"; - neopdf_grid_free(grid); - continue; - } - - // Add grid to collection - int add_grid = neopdf_gridarray_collection_add_grid(collection, grid); - if (add_grid != NEOPDF_RESULT_SUCCESS) { - std::cerr << "Failed to add grid to collection for member: " << m << "!\n"; - neopdf_grid_free(grid); - continue; } std::cout << "Added grid for member " << m << "\n"; } // Fill the running of alphas with some random values - double alphas_qs[] = {2.0}; - double alphas_vals[] = {0.118}; + std::vector alphas_qs = {2.0}; + std::vector alphas_vals = {0.118}; // Extract the ranges for the momentum x and scale Q2 auto x_range = ref_pdf.param_range(NEOPDF_SUBGRID_PARAMS_MOMENTUM); auto q2_range = ref_pdf.param_range(NEOPDF_SUBGRID_PARAMS_SCALE); - NeoPDFMetaData meta = { + PhysicsParameters phys_params = { + .flavor_scheme = "variable", + .order_qcd = 2, + .alphas_order_qcd = 2, + .m_w = 80.352, + .m_z = 91.1876, + .m_up = 0.0, + .m_down = 0.0, + .m_strange = 0.0, + .m_charm = 1.51, + .m_bottom = 4.92, + .m_top = 172.5, + }; + + MetaData meta = { .set_desc = "NNPDF40_nnlo_as_01180 collection", .set_index = 0, .num_members = (uint32_t)neo_pdfs.size(), @@ -407,33 +386,32 @@ int main() { .x_max = x_range[1], .q_min = sqrt(q2_range[0]), .q_max = sqrt(q2_range[1]), - .flavors = pids.data(), - .num_flavors = (size_t)pids.size(), + .flavors = pids, .format = "neopdf", .alphas_q_values = alphas_qs, - .num_alphas_q = 1, .alphas_vals = alphas_vals, - .num_alphas_vals = 1, .polarised = false, - .set_type = SET_TYPE_PDF, + .set_type = SET_TYPE_SPACE_LIKE, .interpolator_type = INTERPOLATOR_TYPE_LOG_BICUBIC, .error_type = "replicas", .hadron_pid = 2212, + .phys_params = phys_params, }; // Check if `NEOPDF_DATA_PATH` is defined and store the Grid there. - const char* filename = "check-writer.neopdf.lz4"; + const char* filename = "check-writer-oop.neopdf.lz4"; const char* neopdf_path = std::getenv("NEOPDF_DATA_PATH"); std::string output_path = neopdf_path ? std::string(neopdf_path) + (std::string(neopdf_path).back() == '/' ? "" : "/") + filename : filename; // Write the PDF Grid into disk - int result = neopdf_grid_compress(collection, &meta, output_path.c_str()); - if (result != 0) { - std::cerr << "Compression failed with code " << result << "\n"; - } else { - std::cout << "Compression succeeded!" << "\n"; + try { + writer.compress(meta, output_path); + std::cout << "Compression succeeded!\n"; + } catch (const std::runtime_error& err) { + std::cerr << "Compression failed: " << err.what() << "\n"; + return EXIT_FAILURE; } // If `NEOPDF_DATA_PATH` is defined, reload the grid and check ther results. @@ -454,7 +432,7 @@ int main() { assert(std::abs(res2 - ref2) < TOLERANCE); } - return result == 0 ? 0 : 1; + return EXIT_SUCCESS; } ``` diff --git a/docs/examples/c.md b/docs/examples/c.md index d6d95b79..c27f1a59 100644 --- a/docs/examples/c.md +++ b/docs/examples/c.md @@ -215,7 +215,7 @@ the process of constructing a grid for each PDF member and serializing the colle is correct. However, this makes the codes very verbose. To easily spot the parts that actually fills the grid, some lines are highlighted. -```cpp linenums="1" hl_lines="110-119 122-130 139 147 166-186 196" +```cpp linenums="1" hl_lines="112-121 124-132 141 149 168-180 182-203 213" #include #include #include @@ -320,11 +320,13 @@ int main() { auto q2s = extract_subgrid_params(pdf, NEOPDF_SUBGRID_PARAMS_SCALE, subgrid_idx, num_subgrids); auto alphas = extract_subgrid_params(pdf, NEOPDF_SUBGRID_PARAMS_ALPHAS, subgrid_idx, num_subgrids); auto nucleons = extract_subgrid_params(pdf, NEOPDF_SUBGRID_PARAMS_NUCLEONS, subgrid_idx, num_subgrids); + auto kts = extract_subgrid_params(pdf, NEOPDF_SUBGRID_PARAMS_KT, subgrid_idx, num_subgrids); // Compute grid_data: [q2s][xs][flavors], instead of [nucleons][alphas][q2s][xs][flavors] // NOTE: This assumes that there is no 'A' and `alphas` dependence. assert(nucleons.size() == 1); assert(alphas.size() == 1); + assert(kts.size() == 1); std::vector grid_data; for (size_t xi = 0; xi < xs.size(); ++xi) { for (size_t qi = 0; qi < q2s.size(); ++qi) { @@ -381,6 +383,20 @@ int main() { neopdf_pdf_param_range(neo_pdfs.pdfs[0], NEOPDF_SUBGRID_PARAMS_MOMENTUM, x_range.data()); neopdf_pdf_param_range(neo_pdfs.pdfs[0], NEOPDF_SUBGRID_PARAMS_SCALE, q2_range.data()); + NeoPDFPhysicsParameters phys_params = { + .flavor_scheme = "variable", + .order_qcd = 2, + .alphas_order_qcd = 2, + .m_w = 80.352, + .m_z = 91.1876, + .m_up = 0.0, + .m_down = 0.0, + .m_strange = 0.0, + .m_charm = 1.51, + .m_bottom = 4.92, + .m_top = 172.5, + }; + NeoPDFMetaData meta = { .set_desc = "NNPDF40_nnlo_as_01180 collection", .set_index = 0, @@ -397,10 +413,11 @@ int main() { .alphas_vals = alphas_vals, .num_alphas_vals = 1, .polarised = false, - .set_type = SET_TYPE_PDF, + .set_type = SET_TYPE_SPACE_LIKE, .interpolator_type = INTERPOLATOR_TYPE_LOG_BICUBIC, .error_type = "replicas", .hadron_pid = 2212, + .phys_params = phys_params, }; // Check if `NEOPDF_DATA_PATH` is defined and store the Grid there. @@ -439,7 +456,7 @@ int main() { neopdf_pdf_free(wpdf); } - // Remove objects from memory. + // Cleanup neopdf_gridarray_collection_free(collection); neopdf_pdf_array_free(neo_pdfs); diff --git a/docs/examples/neopdf-pyapi.ipynb b/docs/examples/neopdf-pyapi.ipynb index d4931044..c8a0bca4 100644 --- a/docs/examples/neopdf-pyapi.ipynb +++ b/docs/examples/neopdf-pyapi.ipynb @@ -40,44 +40,37 @@ "metadata": {}, "outputs": [], "source": [ + "# To load NeoPDF sets, if available, append the name with `.neopdf.lz4`\n", "pdf = NEOPDF.mkPDF(\"NNPDF40_nnlo_as_01180\")" ] }, { "cell_type": "code", "execution_count": 3, - "id": "8d70c779-2044-4948-bc3d-d631d37efa61", - "metadata": {}, - "outputs": [], - "source": [ - "metadata = pdf.metadata()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "2b869801-26de-473e-a0ad-04b4a470ef85", + "id": "a596b193-277e-4d82-ab2a-381739a26692", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "dict_keys(['set_desc', 'set_index', 'num_members', 'x_min', 'x_max', 'q_min', 'q_max', 'flavors', 'format', 'alphas_q_values', 'alphas_vals', 'polarised', 'set_type', 'interpolator_type'])" + "dict_keys(['set_desc', 'set_index', 'num_members', 'x_min', 'x_max', 'q_min', 'q_max', 'flavors', 'format', 'alphas_q_values', 'alphas_vals', 'polarised', 'set_type', 'interpolator_type', 'error_type', 'hadron_pid', 'git_version', 'code_version', 'flavor_scheme', 'order_qcd', 'alphas_order_qcd', 'm_w', 'm_z', 'm_up', 'm_down', 'm_strange', 'm_charm', 'm_bottom', 'm_top'])" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "# Get the Metadata of the PDF set.\n", + "metadata = pdf.metadata()\n", "metadata_dict = metadata.to_dict()\n", "metadata_dict.keys()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "722085ca-46bf-4777-9074-84c4c9713040", "metadata": {}, "outputs": [ @@ -87,7 +80,7 @@ "'NNPDF4.0 NNLO global fit, alphas(MZ)=0.1180. mem=0 => average on replicas; mem=1-100 => PDF replicas'" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -98,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "b2d777bf-b520-4631-aa1d-111fdfa03bf2", "metadata": {}, "outputs": [ @@ -108,7 +101,7 @@ "[0.33074891, 0.3176246, 0.30507081, 0.29305875]" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -119,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "f601e936-ed5d-45a3-b3c2-174f85549e9b", "metadata": {}, "outputs": [ @@ -129,7 +122,7 @@ "'PDF'" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -148,17 +141,17 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "02222876-6053-4eae-b0ea-a83340891018", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(1, 1, 11, 196, 12)" + "(1, 1, 11, 1, 196, 12)" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -178,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "34af3282-1d35-4c52-a2ac-7218510d2c82", "metadata": {}, "outputs": [ @@ -188,7 +181,7 @@ "0.2485925816007479" ] }, - "execution_count": 9, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -199,7 +192,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "b10b018b-9121-4ce0-821e-6315984ff174", "metadata": {}, "outputs": [ @@ -209,7 +202,7 @@ "111.20984759980468" ] }, - "execution_count": 10, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -228,7 +221,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "9581dd94-262e-4e67-8060-661c25d3465d", "metadata": {}, "outputs": [ @@ -238,7 +231,7 @@ "12.628715124538546" ] }, - "execution_count": 11, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -277,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "f202b078-568d-4521-adce-ce13641ef692", "metadata": {}, "outputs": [], @@ -287,12 +280,12 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "id": "a5948b20-6ff4-4708-91d4-581b92c4d5fc", "metadata": {}, "outputs": [], "source": [ - "# NeoPDF files should be appended with `neopdf.lz4`\n", + "# NeoPDF files should be appended with the suffix `neopdf.lz4`\n", "convert_lhapdf(\n", " pdf_name=\"NNPDF40_nnlo_as_01180\", output_path=\"NNPDF40_nnlo_as_01180.neopdf.lz4\"\n", ")" @@ -308,7 +301,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "id": "05787fe5-aa97-426b-b302-675a51ca4adc", "metadata": {}, "outputs": [ @@ -318,7 +311,7 @@ "111.20984759980468" ] }, - "execution_count": 14, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -340,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "id": "3c606842-7b36-4801-b293-b00b4cadfef0", "metadata": {}, "outputs": [], @@ -348,12 +341,12 @@ "# Some imports\n", "from neopdf.writer import compress\n", "from neopdf.gridpdf import GridArray, SubGrid\n", - "from neopdf.metadata import InterpolatorType, SetType, MetaData" + "from neopdf.metadata import InterpolatorType, SetType, MetaData, PhysicsParameters" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "id": "e1bfd9ad-5fe3-4639-9d91-ecc560d2246e", "metadata": {}, "outputs": [], @@ -369,6 +362,24 @@ "alphas_vals = np.random.uniform(0.1, 0.2, num_alphas)\n", "alphas_qvalues = np.geomspace(q_min, q_max, num_alphas)\n", "\n", + "# Define the Physical Parameters in the Metadata\n", + "physparams_kwargs = {\n", + " \"flavor_scheme\": \"fixed\",\n", + " \"order_qcd\": 2,\n", + " \"alphas_order_qcd\": 2,\n", + " \"m_w\": 80.3520,\n", + " \"m_z\": 91.1876,\n", + " \"m_up\": 0.0,\n", + " \"m_down\": 0.0,\n", + " \"m_strange\": 0.0,\n", + " \"m_charm\": 1.51,\n", + " \"m_bottom\": 4.92,\n", + " \"m_top\": 172.5,\n", + "}\n", + "\n", + "phys_params = PhysicsParameters(**physparams_kwargs)\n", + "\n", + "# Construct the PDF Metadata\n", "metadata_kwargs = {\n", " \"set_desc\": \"Some Toy NeoPDF set\",\n", " \"set_index\": 123456,\n", @@ -382,8 +393,9 @@ " \"alphas_q_values\": alphas_qvalues,\n", " \"alphas_vals\": alphas_vals,\n", " \"polarised\": False,\n", - " \"set_type\": SetType.Pdf,\n", + " \"set_type\": SetType.SpaceLike,\n", " \"interpolator_type\": InterpolatorType.LogBicubic,\n", + " \"phys_params\": phys_params,\n", "}\n", "\n", "metadata = MetaData(**metadata_kwargs)" @@ -391,7 +403,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "id": "6c2094e7-8166-4ccd-8ac3-590850775bcf", "metadata": {}, "outputs": [], @@ -402,6 +414,7 @@ "\n", "nucleons = [1] # Proton Only\n", "alphas_mZ = [0.118] # Only one value\n", + "kts = [0.0] # No dependence on the Transverse Momentum\n", "grid_members = []\n", "\n", "x_values = np.geomspace(x_min, x_max, 50)\n", @@ -418,6 +431,7 @@ " len(nucleons),\n", " len(alphas_mZ),\n", " len(flavors),\n", + " len(kts),\n", " x_values.size,\n", " q2_vals.size,\n", " )\n", @@ -426,6 +440,7 @@ " sub_grid = SubGrid(\n", " xs=x_values,\n", " q2s=q2_vals,\n", + " kts=kts,\n", " nucleons=nucleons,\n", " alphas=alphas_mZ,\n", " grid=grid,\n", @@ -461,7 +476,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "id": "116ebc63-cdbc-4960-a03b-56323de830c0", "metadata": {}, "outputs": [], @@ -471,7 +486,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "id": "86e3c2d8-938b-47e7-ac5f-714becb55d5a", "metadata": {}, "outputs": [], @@ -500,7 +515,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "id": "73836cba-3e16-4916-b0bd-ef4eb1fca95c", "metadata": {}, "outputs": [], @@ -510,7 +525,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "id": "a43dd711-b3fe-4d3e-bb52-30c22be2b339", "metadata": {}, "outputs": [ @@ -520,7 +535,7 @@ "134.7438112942475" ] }, - "execution_count": 21, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -540,7 +555,7 @@ "```Python\n", "A_value = 5\n", "alphas_value = 0.117\n", - "nuclear_neopdfs.xfxQ2_ND(21, [A_value, alphas_value, 1e-5, 1e3]) # In that order\n", + "nuclear_neopdfs.xfxQ2_ND(21, [A_value, alphas_value, 1e-5, 1e3]) # Note the Order\n", "```" ] } From 81ea04aaa054087435fa0e672a9553197478c437 Mon Sep 17 00:00:00 2001 From: Radonirinaunimi Date: Tue, 22 Jul 2025 22:35:58 +0200 Subject: [PATCH 4/4] Unify caching and downloading of data --- .github/actions/cache-data/action.yml | 19 +++++++++++++++++++ .github/workflows/benchmarks.yml | 12 +----------- .github/workflows/run-tests.yml | 11 +---------- 3 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 .github/actions/cache-data/action.yml diff --git a/.github/actions/cache-data/action.yml b/.github/actions/cache-data/action.yml new file mode 100644 index 00000000..cfb7f9a9 --- /dev/null +++ b/.github/actions/cache-data/action.yml @@ -0,0 +1,19 @@ +# .github/actions/cache-data/action.yml + +name: Cache Data for the Tests +description: Caches and downloads data +runs: + using: "composite" + steps: + - name: Cache data + id: cache-data + uses: actions/cache@v4 + with: + path: neopdf-data + key: data-v4 + - name: Download data if cache miss + if: steps.cache-data.outputs.cache-hit != 'true' + run: | + cd maintainer + ./download-data.sh + shell: bash diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index bd8bde3d..22120433 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -20,17 +20,7 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Get data - id: cache-data - uses: actions/cache@v4 - with: - path: neopdf-data - key: data-v3 - - - name: Download data - if: steps.cache-data.outputs.cache-hit != 'true' - run: | - cd maintainer - ./download-data.sh + uses: ./.github/actions/cache-data - name: Cache Criterion baseline uses: actions/cache@v4 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 79ee9b68..5f6927e3 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -19,16 +19,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Get data - id: cache-data - uses: actions/cache@v4 - with: - path: neopdf-data - key: data-v3 - - name: Download data - if: steps.cache-data.outputs.cache-hit != 'true' - run: | - cd maintainer - ./download-data.sh + uses: ./.github/actions/cache-data - name: Build NeoPDF crate 🦀 run: cargo build --release - name: Run tests 🚀