diff --git a/examples/cpp/advanced-filling.cpp b/examples/cpp/advanced-filling.cpp index 8c7a4a72d..7b8be66c1 100644 --- a/examples/cpp/advanced-filling.cpp +++ b/examples/cpp/advanced-filling.cpp @@ -11,10 +11,10 @@ int main() { // Construct the channel object based on the nb of convolutions std::size_t nb_convolutions = 2; std::size_t nb_channels = 2; - auto* channels = pineappl_channels_new(); + auto* channels = pineappl_channels_new(nb_convolutions); int32_t pids[] = { 2, -2, 4, -4 }; double factors[] = { 1.0, 1.0 }; - pineappl_channels_add(channels, nb_channels, nb_convolutions, pids, factors); + pineappl_channels_add(channels, nb_channels, pids, factors); std::size_t channel_count = 1; @@ -37,10 +37,10 @@ int main() { // hadrons. Then we add the corresponding PID of each of the hadrons, and finally define the // Basis onto which the partons are mapped. pineappl_pid_basis pid_basis = PINEAPPL_PID_BASIS_EVOL; - int32_t pdg_ids[2] = { 2212, 2212}; - pineappl_conv_type h1 = PINEAPPL_CONV_TYPE_UNPOL_PDF; - pineappl_conv_type h2 = PINEAPPL_CONV_TYPE_UNPOL_PDF; - pineappl_conv_type convolution_types[2] = { h1, h2 }; + pineappl_conv convs[] = { + { PINEAPPL_CONV_TYPE_UNPOL_PDF, 2212 }, + { PINEAPPL_CONV_TYPE_UNPOL_PDF, 2212 }, + }; // Define the kinematics required for this process. In the following example we have ONE // single scale and two momentum fractions (corresponding to the two initial-state hadrons). @@ -56,14 +56,16 @@ int main() { pineappl_map scales_mapping = PINEAPPL_MAP_APPL_GRID_H0; // Mapping method pineappl_map moment_mapping = PINEAPPL_MAP_APPL_GRID_F2; pineappl_interp_meth interpolation_meth = PINEAPPL_INTERP_METH_LAGRANGE; - pineappl_interp_tuples interpolations[3] = { + pineappl_interp interpolations[3] = { { 1e2, 1e8, 40, 3, scales_reweight, scales_mapping, interpolation_meth }, // Interpolation fo `scales` { 2e-7, 1.0, 50, 3, moment_reweight, moment_mapping, interpolation_meth }, // Interpolation fo `x1` { 2e-7, 1.0, 50, 3, moment_reweight, moment_mapping, interpolation_meth }, // Interpolation fo `x2` }; // Define the unphysical scale objecs - size_t mu_scales[] = { 1, 1, 0 }; + pineappl_scale_func_form scale_mu = { PINEAPPL_SCALE_FUNC_FORM_SCALE, 0 }; + pineappl_scale_func_form no_scale_mu = { PINEAPPL_SCALE_FUNC_FORM_NO_SCALE, 0 }; // Here `.scale=0` is dummy value + pineappl_scale_func_form mu_scales[3] = { scale_mu, scale_mu, no_scale_mu }; // --- // Create the grid using the previously set information about orders, bins and channels @@ -71,8 +73,8 @@ int main() { // create a new grid with the previously defined channels, 3 perturbative orders defined by the // exponents in `orders`, 24 bins given as the 25 limits in `bins` and potential extra // parameters in `keyval`. - auto* grid = pineappl_grid_new2(pid_basis, channels, orders.size() / 5, orders.data(), bins.size() - 1, - bins.data(), nb_convolutions, convolution_types, pdg_ids, kinematics, interpolations, mu_scales); + auto* grid = pineappl_grid_new2(bins.size() - 1, bins.data(), orders.size() / 5, orders.data(), + channels, pid_basis, convs, 3, interpolations, kinematics, mu_scales); // now we no longer need `channels` pineappl_channels_delete(channels); diff --git a/examples/cpp/fill-grid.cpp b/examples/cpp/fill-grid.cpp index b45c49396..e56e8a4b6 100644 --- a/examples/cpp/fill-grid.cpp +++ b/examples/cpp/fill-grid.cpp @@ -115,11 +115,9 @@ int main() { // --- // Create all channels - // this object will contain all channels (initial states) that we define - auto* channels = pineappl_channels_new(); - - // Specify the dimension of the channel, ie the number of convolutions required + // this object will contain all channels (for two initial states) that we define std::size_t nb_convolutions = 2; + auto* channels = pineappl_channels_new(nb_convolutions); // photon-photon initial state, where `22` is the photon (PDG MC ids) int32_t pids1[] = { 22, 22 }; @@ -128,7 +126,7 @@ int main() { double factors1[] = { 1.0 }; // define the channel #0 - pineappl_channels_add(channels, 1, nb_convolutions, pids1, factors1); + pineappl_channels_add(channels, 1, pids1, factors1); // create another channel, which we won't fill, however @@ -143,7 +141,7 @@ int main() { // can also pass `nullptr` // define the channel #1 - pineappl_channels_add(channels, 3, nb_convolutions, pids2, nullptr); + pineappl_channels_add(channels, 3, pids2, nullptr); // --- // Specify the perturbative orders that will be filled into the grid @@ -182,10 +180,10 @@ int main() { // hadrons. Then we add the corresponding PID of each of the hadrons, and finally define the // Basis onto which the partons are mapped. pineappl_pid_basis pid_basis = PINEAPPL_PID_BASIS_EVOL; - int32_t pdg_ids[2] = { 2212, 2212}; - pineappl_conv_type h1 = PINEAPPL_CONV_TYPE_UNPOL_PDF; - pineappl_conv_type h2 = PINEAPPL_CONV_TYPE_UNPOL_PDF; - pineappl_conv_type convolution_types[2] = { h1, h2 }; + pineappl_conv convs[] = { + { PINEAPPL_CONV_TYPE_UNPOL_PDF, 2212 }, + { PINEAPPL_CONV_TYPE_UNPOL_PDF, 2212 }, + }; // Define the kinematics required for this process. In the following example we have ONE // single scale and two momentum fractions (corresponding to the two initial-state hadrons). @@ -201,14 +199,16 @@ int main() { pineappl_map scales_mapping = PINEAPPL_MAP_APPL_GRID_H0; // Mapping method pineappl_map moment_mapping = PINEAPPL_MAP_APPL_GRID_F2; pineappl_interp_meth interpolation_meth = PINEAPPL_INTERP_METH_LAGRANGE; - pineappl_interp_tuples interpolations[3] = { + pineappl_interp interpolations[3] = { { 1e2, 1e8, 40, 3, scales_reweight, scales_mapping, interpolation_meth }, // Interpolation fo `scales` { 2e-7, 1.0, 50, 3, moment_reweight, moment_mapping, interpolation_meth }, // Interpolation fo `x1` { 2e-7, 1.0, 50, 3, moment_reweight, moment_mapping, interpolation_meth }, // Interpolation fo `x2` }; // Define the unphysical scale objecs - size_t mu_scales[] = { 1, 1, 0 }; + pineappl_scale_func_form scale_mu = { PINEAPPL_SCALE_FUNC_FORM_SCALE, 0 }; + pineappl_scale_func_form no_scale_mu = { PINEAPPL_SCALE_FUNC_FORM_NO_SCALE, 0 }; // Here `.scale=0` is dummy value + pineappl_scale_func_form mu_scales[3] = { scale_mu, scale_mu, no_scale_mu }; // --- // Create the grid using the previously set information about orders, bins and channels @@ -216,8 +216,8 @@ int main() { // create a new grid with the previously defined channels, 3 perturbative orders defined by the // exponents in `orders`, 24 bins given as the 25 limits in `bins` and potential extra // parameters in `keyval`. - auto* grid = pineappl_grid_new2(pid_basis, channels, orders.size() / 5, orders.data(), bins.size() - 1, - bins.data(), nb_convolutions, convolution_types, pdg_ids, kinematics, interpolations, mu_scales); + auto* grid = pineappl_grid_new2(bins.size() - 1, bins.data(), orders.size() / 5, orders.data(), + channels, pid_basis, convs, 3, interpolations, kinematics, mu_scales); // now we no longer need `keyval` and `channels` pineappl_channels_delete(channels); diff --git a/examples/fortran/lhapdf_example.f90 b/examples/fortran/lhapdf_example.f90 index 8d187dd9b..5f465e586 100644 --- a/examples/fortran/lhapdf_example.f90 +++ b/examples/fortran/lhapdf_example.f90 @@ -6,10 +6,12 @@ program lhapdf_example integer, parameter :: dp = kind(0.0d0) - type(pineappl_grid) :: grid - type(pineappl_channels) :: channels - type(pineappl_kinematics) :: kinematics(3) - type(pineappl_interp_tuples) :: interpolations(3) + type(pineappl_grid) :: grid + type(pineappl_channels) :: channels + type(pineappl_kinematics) :: kinematics(3) + type(pineappl_scale_func_form) :: mu_scales_form(3) + type(pineappl_interp) :: interp_info(3) + type(pineappl_conv) :: convolutions(2) type(pineappl_xfx) :: xfx type(pineappl_alphas) :: alphas @@ -25,8 +27,8 @@ program lhapdf_example integer(c_int), target :: pdfs_array(2,2) character(len=30) :: pdfset1, pdfset2 - channels = pineappl_channels_new() - call pineappl_channels_add(channels, 3, 2, [0, 0, 1, -1, 2, -2], [1.0_dp, 1.0_dp, 1.0_dp]) + channels = pineappl_channels_new(2) ! The argument is the number of convolutions + call pineappl_channels_add(channels, 3, [0, 0, 1, -1, 2, -2], [1.0_dp, 1.0_dp, 1.0_dp]) kinematics = [& pineappl_kinematics(pineappl_scale, 0), & @@ -39,14 +41,26 @@ program lhapdf_example q2_mapping = pineappl_applgrid_h0 x_mapping = pineappl_applgrid_f2 interpolation_meth = pineappl_lagrange - interpolations = [ & - pineappl_interp_tuples(1e2_dp, 1e8_dp, 40, 3, q2_reweight, q2_mapping, interpolation_meth), & - pineappl_interp_tuples(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth), & - pineappl_interp_tuples(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth) & + interp_info = [ & + pineappl_interp(1e2_dp, 1e8_dp, 40, 3, q2_reweight, q2_mapping, interpolation_meth), & + pineappl_interp(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth), & + pineappl_interp(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth) & ] - grid = pineappl_grid_new2(pineappl_pdg, channels, 1, [2_1, 0_1, 0_1, 0_1, 0_1], 2, & - [0.0_dp, 1.0_dp, 2.0_dp], 2, [pineappl_unpol_pdf, pineappl_unpol_pdf], [2212, 2212], kinematics, interpolations, [1, 1, 0]) + ! The `pineappl_scale_func_form_body` objects have to defined with two fields - if not required, the value(s) will be ignored + mu_scales_form = [ & + pineappl_scale_func_form(PINEAPPL_SCALE_FUNC_FORM_SCALE, pineappl_scale_func_form_body(0, 0)), & + pineappl_scale_func_form(PINEAPPL_SCALE_FUNC_FORM_SCALE, pineappl_scale_func_form_body(0, 0)), & + pineappl_scale_func_form(PINEAPPL_SCALE_FUNC_FORM_NO_SCALE, pineappl_scale_func_form_body(0, 0)) & + ] + + convolutions = [ & + pineappl_conv(pineappl_unpol_pdf, 2212), & + pineappl_conv(pineappl_unpol_pdf, 2212) & + ] + + grid = pineappl_grid_new2(2, [0.0_dp, 1.0_dp, 2.0_dp], 1, [2_1, 0_1, 0_1, 0_1, 0_1], channels, pineappl_pdg, & + convolutions, 3, interp_info, kinematics, mu_scales_form) call pineappl_grid_fill_all2(grid, 0, 0.5_dp, [100.0_dp, 0.5_dp, 0.5_dp], [0.5_dp, 0.5_dp, 0.5_dp]) call pineappl_grid_fill_all2(grid, 0, 1.5_dp, [100.0_dp, 0.5_dp, 0.5_dp], [1.5_dp, 1.5_dp, 1.5_dp]) diff --git a/examples/fortran/pineappl.f90 b/examples/fortran/pineappl.f90 index e84c14f55..bab3c4424 100644 --- a/examples/fortran/pineappl.f90 +++ b/examples/fortran/pineappl.f90 @@ -68,17 +68,53 @@ module pineappl enumerator :: pineappl_kinematics_tag end enum - ! The Kinematics struct is a tuple-like struct in the Pineappl Rust code, which is realized as a C union. Fortran does not support unions, but fortunately the union is only for storing ints, so we just use an integer variable for `index` + enum, bind(c) ! :: pineappl_scale_func_form_tag + enumerator :: pineappl_scale_func_form_no_scale + enumerator :: pineappl_scale_func_form_scale + enumerator :: pineappl_scale_func_form_quadratic_sum + enumerator :: pineappl_scale_func_form_quadratic_mean + enumerator :: pineappl_scale_func_form_quadratic_sum_over4 + enumerator :: pineappl_scale_func_form_linear_mean + enumerator :: pineappl_scale_func_form_linear_sum + enumerator :: pineappl_scale_func_form_scale_max + enumerator :: pineappl_scale_func_form_scale_min + enumerator :: pineappl_scale_func_form_prod + enumerator :: pineappl_scale_func_form_s2plus_s1half + enumerator :: pineappl_scale_func_form_pow4_sum + enumerator :: pineappl_scale_func_form_wgt_avg + enumerator :: pineappl_scale_func_form_s2plus_s1fourth + enumerator :: pineappl_scale_func_form_exp_prod2 + + enumerator :: pineappl_scale_func_form_tag + end enum + + ! The Kinematics struct is a tuple-like struct in the PineAPPL Rust code, which is realized as a C union. Fortran does not support unions, but fortunately the union is only for storing ints, so we just use an integer variable for `index` type, bind(c) :: pineappl_kinematics integer(kind(pineappl_kinematics_tag)) :: tag integer(c_size_t) :: index end type - type, bind(c) :: pineappl_interp_tuples - real(c_double) :: node_min - real(c_double) :: node_max - integer(c_size_t) :: nb_nodes - integer(c_size_t) :: interp_degree + ! Implement the ScaleFuncForm struct which is also a tuple-like struct ine PineAPPL Rust code. The `pineappl_scale_func_form_body` objects have to defined with two fields - if not required, the value(s) will be ignored. + type, bind(c) :: pineappl_scale_func_form_body + integer(c_size_t) :: index_0 ! index_0 maps to C union field _0 + integer(c_size_t) :: index_1 ! index_1 maps to C union field _1 + end type + + type, bind(c) :: pineappl_scale_func_form + integer(kind(pineappl_scale_func_form_tag)) :: tag + type(pineappl_scale_func_form_body) :: body + end type + + type, bind(c) :: pineappl_conv + integer(kind(pineappl_conv_type)) :: conv_type + integer(c_int32_t) :: pid + end type + + type, bind(c) :: pineappl_interp + real(c_double) :: min + real(c_double) :: max + integer(c_size_t) :: nodes + integer(c_size_t) :: order integer(kind(pineappl_reweight_meth)) :: reweighting_method integer(kind(pineappl_map)) :: mapping integer(kind(pineappl_interp_meth)) :: interpolation_method @@ -125,18 +161,19 @@ function strlen(s) bind(c, name="strlen") integer (c_size_t) :: strlen end function strlen - subroutine channels_add(channels, combinations, nb_combinations, pdg_id_combinations, factors) & + subroutine channels_add(channels, combinations, pdg_id_combinations, factors) & bind(c, name = 'pineappl_channels_add') use iso_c_binding type (c_ptr), value :: channels - integer (c_size_t), value :: combinations, nb_combinations + integer (c_size_t), value :: combinations integer (c_int32_t) :: pdg_id_combinations(*) real (c_double) :: factors(*) end subroutine - type (c_ptr) function channels_new() bind(c, name = 'pineappl_channels_new') + type (c_ptr) function channels_new(convolutions) bind(c, name = 'pineappl_channels_new') use iso_c_binding + integer (c_int32_t), value :: convolutions end function integer (c_size_t) function grid_bin_count(grid) bind(c, name = 'pineappl_grid_bin_count') @@ -312,21 +349,21 @@ type (c_ptr) function grid_new(lumi, orders, order_params, bins, bin_limits, key real (c_double) :: bin_limits(*) end function - type (c_ptr) function grid_new2(pid_basis, channels, orders, order_params, bins, bin_limits, nb_convolutions, & - convolution_types, pdg_ids, kinematics, interpolations, mu_scales) bind(c, name = 'pineappl_grid_new2') + type (c_ptr) function grid_new2(bins, bin_limits, orders, order_params, channels, & + pid_basis, convolutions, interpolations, interp_info, & + kinematics, mu_scales) bind(c, name = 'pineappl_grid_new2') use iso_c_binding - import ! so we can use pineappl_kinematics and pineappl_interp_tuples + import ! so we can use pineappl_kinematics and pineappl_interp integer (c_int32_t), value :: pid_basis type (c_ptr), value :: channels - integer (c_int32_t) :: convolution_types(*) - integer (c_size_t), value :: orders, bins, nb_convolutions + integer (c_size_t), value :: orders, bins, interpolations integer (c_int8_t) :: order_params(*) real (c_double) :: bin_limits(*) - integer (c_int32_t) :: pdg_ids(*) + type (pineappl_conv) :: convolutions(*) type (pineappl_kinematics) :: kinematics(*) - type (pineappl_interp_tuples) :: interpolations(*) - integer (c_size_t) :: mu_scales(*) + type (pineappl_interp) :: interp_info(*) + type (pineappl_scale_func_form) :: mu_scales(*) end function subroutine grid_optimize(grid) bind(c, name = 'pineappl_grid_optimize') @@ -557,10 +594,12 @@ function c_f_string(c_str) result(f_str) end do end function - type (pineappl_channels) function pineappl_channels_new() + type (pineappl_channels) function pineappl_channels_new(convolutions) implicit none - pineappl_channels_new = pineappl_channels(channels_new()) + integer (c_int32_t), value :: convolutions + + pineappl_channels_new = pineappl_channels(channels_new(convolutions)) end function integer function pineappl_grid_bin_count(grid) @@ -896,37 +935,34 @@ type (pineappl_grid) function pineappl_grid_new(lumi, orders, order_params, bins order_params, int(bins, c_size_t), bin_limits, key_vals%ptr)) end function - type (pineappl_grid) function pineappl_grid_new2(pid_basis, channels, orders, order_params, & - bins, bin_limits, nb_convolutions, convolution_types, pdg_ids, kinematics, & - interpolations, mu_scales) + type (pineappl_grid) function pineappl_grid_new2(bins, bin_limits, orders, order_params, & + channels, pid_basis, convolutions, interpolations, interp_info, kinematics, mu_scales) implicit none integer(kind(pineappl_pid_basis)), intent(in) :: pid_basis type (pineappl_channels), intent(in) :: channels - integer, intent(in) :: orders, bins, nb_convolutions + integer, intent(in) :: orders, bins, interpolations integer(int8), dimension(5 * orders), intent(in) :: order_params real (dp), dimension(bins + 1), intent(in) :: bin_limits - integer(kind(pineappl_conv_type)), dimension(nb_convolutions), intent(in) :: convolution_types - integer, dimension(nb_convolutions), intent(in) :: pdg_ids - type (pineappl_kinematics), dimension(nb_convolutions + 1), intent(in), target :: kinematics - type (pineappl_interp_tuples), dimension(nb_convolutions + 1), intent(in) :: interpolations - integer, dimension(3) :: mu_scales + type (pineappl_conv), dimension(*), intent(in), target :: convolutions + type (pineappl_kinematics), dimension(interpolations), intent(in), target :: kinematics + type (pineappl_interp), dimension(interpolations), intent(in) :: interp_info + type (pineappl_scale_func_form), dimension(interpolations) :: mu_scales integer :: i pineappl_grid_new2 = pineappl_grid(grid_new2(& - pid_basis, & - channels%ptr, & - int(orders, c_size_t), & - order_params, & int(bins, c_size_t), & bin_limits, & - int(nb_convolutions, c_size_t), & - convolution_types, & - pdg_ids, & + int(orders, c_size_t), & + order_params, & + channels%ptr, & + pid_basis, & + convolutions, & + int(interpolations, c_size_t), & + interp_info, & kinematics, & - interpolations, & - [(int(mu_scales(i), c_size_t), i = 1, size(mu_scales))]) & + mu_scales) & ) end function @@ -1177,17 +1213,17 @@ subroutine pineappl_lumi_add(lumi, combinations, pdg_id_pairs, factors) call lumi_add(lumi%ptr, int(combinations, c_size_t), pdg_id_pairs, factors) end subroutine - subroutine pineappl_channels_add(channels, combinations, nb_combinations, pdg_id_combinations, factors) + subroutine pineappl_channels_add(channels, combinations, pdg_id_combinations, factors) use iso_c_binding implicit none type (pineappl_channels), intent(in) :: channels - integer, intent(in) :: combinations, nb_combinations + integer, intent(in) :: combinations integer, dimension(2 * combinations), intent(in) :: pdg_id_combinations real (dp), dimension(combinations), intent(in) :: factors - call channels_add(channels%ptr, int(combinations, c_size_t), int(nb_combinations, c_size_t), pdg_id_combinations, factors) + call channels_add(channels%ptr, int(combinations, c_size_t), pdg_id_combinations, factors) end subroutine integer function pineappl_lumi_combinations(lumi, entry) diff --git a/examples/fortran/test.f90 b/examples/fortran/test.f90 index b5b65d5ec..ea3ac8d42 100644 --- a/examples/fortran/test.f90 +++ b/examples/fortran/test.f90 @@ -6,10 +6,12 @@ program test_pineappl integer, parameter :: dp = kind(0.0d0) - type(pineappl_channels) :: channels, channels2 - type(pineappl_grid) :: grid, grid2 - type(pineappl_kinematics) :: kinematics(3) - type(pineappl_interp_tuples) :: interpolations(3) + type(pineappl_channels) :: channels, channels2 + type(pineappl_grid) :: grid, grid2 + type(pineappl_kinematics) :: kinematics(3) + type(pineappl_scale_func_form) :: mu_scales_form(3) + type(pineappl_interp) :: interp_info(3) + type(pineappl_conv) :: convolutions(2) real(dp), allocatable :: result(:), bin_limits_left(:), bin_limits_right(:), bin_normalizations(:) @@ -25,8 +27,8 @@ program test_pineappl type(c_ptr), target :: pdfs_state(2) integer(c_int), target :: pdfs_array(2,2) - channels = pineappl_channels_new() - call pineappl_channels_add(channels, 3, 2, [0, 0, 1, -1, 2, -2], [1.0_dp, 1.0_dp, 1.0_dp]) + channels = pineappl_channels_new(2) ! The argument is the number of convolutions + call pineappl_channels_add(channels, 3, [0, 0, 1, -1, 2, -2], [1.0_dp, 1.0_dp, 1.0_dp]) if (pineappl_channels_count(channels) /= 1) then write(*, *) "pineappl_channels_count(): ", pineappl_channels_count(channels) @@ -38,7 +40,7 @@ program test_pineappl error stop "error: pineappl_channels_combinations" end if - kinematics = [& + kinematics = [ & pineappl_kinematics(pineappl_scale, 0), & pineappl_kinematics(pineappl_x, 0), & pineappl_kinematics(pineappl_x, 1) & @@ -49,13 +51,26 @@ program test_pineappl q2_mapping = pineappl_applgrid_h0 x_mapping = pineappl_applgrid_f2 interpolation_meth = pineappl_lagrange - interpolations = [ & - pineappl_interp_tuples(1e2_dp, 1e8_dp, 40, 3, q2_reweight, q2_mapping, interpolation_meth), & - pineappl_interp_tuples(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth), & - pineappl_interp_tuples(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth) & + interp_info = [ & + pineappl_interp(1e2_dp, 1e8_dp, 40, 3, q2_reweight, q2_mapping, interpolation_meth), & + pineappl_interp(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth), & + pineappl_interp(2e-7_dp, 1.0_dp, 50, 3, x_reweight, x_mapping, interpolation_meth) & ] - grid = pineappl_grid_new2(pineappl_pdg, channels, 1, [2_1, 0_1, 0_1, 0_1, 0_1], 2, [0.0_dp, 1.0_dp, 2.0_dp], & - 2, [pineappl_unpol_pdf, pineappl_unpol_pdf], [2212, 2212], kinematics, interpolations, [1, 1, 0]) + + ! The `pineappl_scale_func_form_body` objects have to defined with two fields - if not required, the value(s) will be ignored + mu_scales_form = [ & + pineappl_scale_func_form(PINEAPPL_SCALE_FUNC_FORM_SCALE, pineappl_scale_func_form_body(0, 0)), & + pineappl_scale_func_form(PINEAPPL_SCALE_FUNC_FORM_SCALE, pineappl_scale_func_form_body(0, 0)), & + pineappl_scale_func_form(PINEAPPL_SCALE_FUNC_FORM_NO_SCALE, pineappl_scale_func_form_body(0, 0)) & + ] + + convolutions = [ & + pineappl_conv(pineappl_unpol_pdf, 2212), & + pineappl_conv(pineappl_unpol_pdf, 2212) & + ] + + grid = pineappl_grid_new2(2, [0.0_dp, 1.0_dp, 2.0_dp], 1, [2_1, 0_1, 0_1, 0_1, 0_1], channels, pineappl_pdg, & + convolutions, 3, interp_info, kinematics, mu_scales_form) if (pineappl_grid_order_count(grid) /= 1) then write(*, *) "pineappl_grid_order_count(): ", pineappl_grid_order_count(grid) @@ -121,8 +136,8 @@ program test_pineappl error stop "error: pineappl_channels_combinations" end if - grid2 = pineappl_grid_new2(pineappl_pdg, channels, 1, [2_1, 0_1, 0_1, 0_1, 0_1], 1, [2.0_dp, 3.0_dp], & - 2, [pineappl_unpol_pdf, pineappl_unpol_pdf], [2212, 2212], kinematics, interpolations, [1, 1, 0]) + grid2 = pineappl_grid_new2(1, [2.0_dp, 3.0_dp], 1, [2_1, 0_1, 0_1, 0_1, 0_1], channels, pineappl_pdg, & + convolutions, 3, interp_info, kinematics, mu_scales_form) call pineappl_grid_merge_and_delete(grid, grid2) diff --git a/examples/object-oriented-cpp/dyaa.cpp b/examples/object-oriented-cpp/dyaa.cpp index 6fad292ef..bdffc142d 100644 --- a/examples/object-oriented-cpp/dyaa.cpp +++ b/examples/object-oriented-cpp/dyaa.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -108,9 +107,10 @@ int main() { // Name of the PDF sets to be used for the convolutions std::string pdfset1 = "NNPDF31_nlo_as_0118_luxqed"; std::string pdfset2 = "MSHT20qed_nnlo"; + const std::size_t nb_convolutions = 2; // --- create a new `Channels` function for the $\gamma\gamma$ initial state - PineAPPL::Channels channels; + PineAPPL::Channels channels(nb_convolutions); PineAPPL::SubChannelEntry subchannels; subchannels.entry.push_back({{22, 22}, 1.0}); PineAPPL::ChannelsEntry channels_entry; @@ -130,12 +130,12 @@ int main() { // --- Construct the PineAPPL grid pineappl_pid_basis pid_basis = PINEAPPL_PID_BASIS_EVOL; - std::vector pids = {2212, 2212}; // Define the types of convolutions - pineappl_conv_type h1 = PINEAPPL_CONV_TYPE_UNPOL_PDF; - pineappl_conv_type h2 = PINEAPPL_CONV_TYPE_UNPOL_PDF; - std::vector convolution_types = {h1, h2}; + std::vector convolutions = { + {PINEAPPL_CONV_TYPE_UNPOL_PDF, 2212}, + {PINEAPPL_CONV_TYPE_UNPOL_PDF, 2212} + }; // Define the Kinematics pineappl_kinematics scales = {PINEAPPL_KINEMATICS_SCALE, 0}; @@ -150,7 +150,7 @@ int main() { pineappl_map scales_mapping = PINEAPPL_MAP_APPL_GRID_H0; // Mapping method pineappl_map moment_mapping = PINEAPPL_MAP_APPL_GRID_F2; pineappl_interp_meth interpolation_meth = PINEAPPL_INTERP_METH_LAGRANGE; - std::vector interpolations = { + std::vector interpolations = { {1e2, 1e8, 40, 3, scales_reweight, scales_mapping, interpolation_meth}, // Interpolation fo `scales` {2e-7, 1.0, 50, 3, moment_reweight, moment_mapping, @@ -159,10 +159,12 @@ int main() { interpolation_meth}, // Interpolation fo `x2` }; - // Define the μ scale - std::vector mu_scales = {1, 1, 1}; + // Define the μ `ScaleFuncForm` objects + pineappl_scale_func_form scale_form = {PINEAPPL_SCALE_FUNC_FORM_SCALE, 0}; + pineappl_scale_func_form no_scale_form = {PINEAPPL_SCALE_FUNC_FORM_NO_SCALE, 0}; + std::vector mu_scales = {scale_form, scale_form, no_scale_form}; - PineAPPL::Grid grid(orders, channels, pid_basis, pids, convolution_types, + PineAPPL::Grid grid(orders, channels, pid_basis, convolutions, kinematics, interpolations, bins, mu_scales); // fill the grid with phase-space points diff --git a/pineappl_capi/Cargo.toml b/pineappl_capi/Cargo.toml index 3ef783b52..ad1bba588 100644 --- a/pineappl_capi/Cargo.toml +++ b/pineappl_capi/Cargo.toml @@ -1,5 +1,8 @@ [package] -authors = ["Christopher Schwan "] +authors = [ + "Christopher Schwan ", + "Tanjona R. Rabemananjara " +] description = "C language interface to PineAPPL" name = "pineappl_capi" readme = "README.md" diff --git a/pineappl_capi/cbindgen.toml b/pineappl_capi/cbindgen.toml index 8a07de992..7d3c65104 100644 --- a/pineappl_capi/cbindgen.toml +++ b/pineappl_capi/cbindgen.toml @@ -4,7 +4,8 @@ language = "C" header = """/* * PineAPPL - PDF-independent binning of phase space weights - * Copyright (C) 2020-2024 Christopher Schwan + * Copyright (C) 2020-2025 Christopher Schwan + * Copyright (C) 2024-2025 Tanjona R. Rabemananjara * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,19 +35,21 @@ prefix_with_name = true rename_variants = "ScreamingSnakeCase" [export.rename] -"Grid" = "pineappl_grid" -"Lumi" = "pineappl_lumi" "Channels" = "pineappl_channels" -"PidBasis" = "pineappl_pid_basis" +"Conv" = "pineappl_conv" "ConvType" = "pineappl_conv_type" -"Kinematics" = "pineappl_kinematics" -"ReweightMeth" = "pineappl_reweight_meth" -"Map" = "pineappl_map" +"Grid" = "pineappl_grid" +"GridOptFlags" = "pineappl_gof" +"Interp" = "pineappl_interp" "InterpMeth" = "pineappl_interp_meth" -"InterpTuples" = "pineappl_interp_tuples" "KeyVal" = "pineappl_keyval" +"Kinematics" = "pineappl_kinematics" +"Lumi" = "pineappl_lumi" +"Map" = "pineappl_map" +"PidBasis" = "pineappl_pid_basis" +"ReweightMeth" = "pineappl_reweight_meth" +"ScaleFuncForm" = "pineappl_scale_func_form" "SubGrid" = "pineappl_subgrid" -"GridOptFlags" = "pineappl_gof" ############## Options for How Your Rust library Should Be Parsed ############## diff --git a/pineappl_capi/include/PineAPPL.hpp b/pineappl_capi/include/PineAPPL.hpp index 20bf0e70c..d7fe1de4e 100644 --- a/pineappl_capi/include/PineAPPL.hpp +++ b/pineappl_capi/include/PineAPPL.hpp @@ -41,7 +41,7 @@ struct Channels { pineappl_channels *raw; /** @brief Constructor. */ - Channels() : raw(pineappl_channels_new()) {} + Channels(const std::size_t convolutions) : raw(pineappl_channels_new(convolutions)) {} Channels(const Channels &) = delete; Channels(Channels &&) = delete; @@ -62,9 +62,6 @@ struct Channels { const std::size_t combinations = c.channels_entry.size(); if (combinations == 0) return; - const std::size_t nb_convolutions = - c.channels_entry[0].entry[0].first.size(); - std::vector pids; std::vector weights; for (const SubChannelEntry &s : c.channels_entry) { @@ -75,8 +72,7 @@ struct Channels { weights.push_back(m.second); } } - pineappl_channels_add(this->raw, combinations, nb_convolutions, pids.data(), - weights.data()); + pineappl_channels_add(this->raw, combinations, pids.data(), weights.data()); } /** @@ -154,21 +150,21 @@ struct Grid { * @param bin_limits bin_limits * @param mu_scales indexes representing the scales */ - Grid(std::vector &orders, const Channels &channels, - pineappl_pid_basis pid_basis, std::vector pids, - std::vector &convolution_types, + Grid(std::vector &orders, + const Channels &channels, + pineappl_pid_basis pid_basis, + std::vector &convolutions, std::vector &kinematics, - std::vector &interp, - std::vector &bin_limits, std::vector &mu_scales) + std::vector &interp, + std::vector &bin_limits, + std::vector &mu_scales) : Grid(nullptr) { const std::size_t n_orders = orders.size(); const std::size_t n_bins = bin_limits.size() - 1; - const std::size_t n_convs = convolution_types.size(); + const std::size_t n_convs = convolutions.size(); // Various checks for the input arguments assert(n_orders >= 1 && "Orders cannot be empty."); - assert(n_convs == pids.size() && - "Number of convolutions and pids are different."); assert(n_convs == kinematics.size() - 1 && "Mismatch in the number of convolutions and the kinematics."); assert(kinematics.size() == interp.size() && @@ -186,9 +182,9 @@ struct Grid { } this->raw = pineappl_grid_new2( - pid_basis, channels.raw, n_orders, raw_orders.data(), n_bins, - bin_limits.data(), n_convs, convolution_types.data(), pids.data(), - kinematics.data(), interp.data(), mu_scales.data()); + n_bins, bin_limits.data(), n_orders, raw_orders.data(), channels.raw, + pid_basis, convolutions.data(), interp.size(), + interp.data(), kinematics.data(), mu_scales.data()); } /** diff --git a/pineappl_capi/src/lib.rs b/pineappl_capi/src/lib.rs index c28ee9616..d36f9a88c 100644 --- a/pineappl_capi/src/lib.rs +++ b/pineappl_capi/src/lib.rs @@ -59,7 +59,7 @@ use itertools::izip; use pineappl::boc::{Bin, BinsWithFillLimits, Channel, Kinematics, Order, ScaleFuncForm, Scales}; use pineappl::convolutions::{Conv, ConvType, ConvolutionCache}; use pineappl::grid::{Grid, GridOptFlags}; -use pineappl::interpolation::{Interp, InterpMeth, Map, ReweightMeth}; +use pineappl::interpolation::{Interp as InterpMain, InterpMeth, Map, ReweightMeth}; use pineappl::packed_array::ravel_multi_index; use pineappl::pids::PidBasis; use pineappl::subgrid::Subgrid; @@ -67,7 +67,7 @@ use std::collections::HashMap; use std::ffi::{CStr, CString}; use std::fs::File; use std::mem; -use std::os::raw::{c_char, c_int, c_void}; +use std::os::raw::{c_char, c_void}; use std::path::Path; use std::slice; @@ -91,7 +91,7 @@ pub const PINEAPPL_GOF_STRIP_EMPTY_CHANNELS: GridOptFlags = GridOptFlags::STRIP_ // TODO: make sure no `panic` calls leave functions marked as `extern "C"` -fn grid_interpolation_params(key_vals: Option<&KeyVal>) -> Vec { +fn grid_interpolation_params(key_vals: Option<&KeyVal>) -> Vec { let mut q2_min = 1e2; let mut q2_max = 1e8; let mut q2_nodes = 40; @@ -213,7 +213,7 @@ fn grid_interpolation_params(key_vals: Option<&KeyVal>) -> Vec { } vec![ - Interp::new( + InterpMain::new( q2_min, q2_max, q2_nodes, @@ -222,7 +222,7 @@ fn grid_interpolation_params(key_vals: Option<&KeyVal>) -> Vec { Map::ApplGridH0, InterpMeth::Lagrange, ), - Interp::new( + InterpMain::new( x1_min, x1_max, x1_nodes, @@ -231,7 +231,7 @@ fn grid_interpolation_params(key_vals: Option<&KeyVal>) -> Vec { Map::ApplGridF2, InterpMeth::Lagrange, ), - Interp::new( + InterpMain::new( x2_min, x2_max, x2_nodes, @@ -368,7 +368,7 @@ pub unsafe extern "C" fn pineappl_grid_clone(grid: *const Grid) -> Box { /// See [`pineappl_grid_convolve_with_one`]. #[deprecated( since = "0.8.0", - note = "please use `pineappl_grid_convolve_with_one` instead" + note = "use `pineappl_grid_convolve_with_one` instead" )] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_convolute_with_one( @@ -406,7 +406,7 @@ pub unsafe extern "C" fn pineappl_grid_convolute_with_one( /// See [`pineappl_grid_convolve_with_two`]. #[deprecated( since = "0.8.0", - note = "please use `pineappl_grid_convolve_with_two` instead" + note = "use `pineappl_grid_convolve_with_two` instead" )] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_convolute_with_two( @@ -601,6 +601,7 @@ pub extern "C" fn pineappl_grid_delete(grid: Option>) {} /// /// If `grid` does not point to a valid `Grid` object, for example when `grid` is the null pointer, /// this function is not safe to call. +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_fill2` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_fill( grid: *mut Grid, @@ -625,6 +626,7 @@ pub unsafe extern "C" fn pineappl_grid_fill( /// /// If `grid` does not point to a valid `Grid` object, for example when `grid` is the null pointer, /// this function is not safe to call. +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_fill_all2` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_fill_all( grid: *mut Grid, @@ -650,6 +652,7 @@ pub unsafe extern "C" fn pineappl_grid_fill_all( /// If `grid` does not point to a valid `Grid` object, for example when `grid` is the null pointer, /// this function is not safe to call. Additionally, all remaining pointer parameters must be /// arrays as long as specified by `size`. +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_fill_array2` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_fill_array( grid: *mut Grid, @@ -684,6 +687,7 @@ pub unsafe extern "C" fn pineappl_grid_fill_array( /// /// If `grid` does not point to a valid `Grid` object, for example when `grid` is the null pointer, /// this function is not safe to call. +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_channels` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_lumi(grid: *const Grid) -> Box { let grid = unsafe { &*grid }; @@ -698,6 +702,7 @@ pub unsafe extern "C" fn pineappl_grid_lumi(grid: *const Grid) -> Box { /// If `grid` does not point to a valid `Grid` object, for example when `grid` is the null pointer, /// this function is not safe to call. The pointer `order_params` must point to an array as large /// as four times the number of orders in `grid`. +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_order_params2` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_order_params(grid: *const Grid, order_params: *mut u32) { let grid = unsafe { &*grid }; @@ -750,6 +755,7 @@ pub unsafe extern "C" fn pineappl_grid_order_count(grid: *const Grid) -> usize { /// # Panics /// /// TODO +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_new2` instead")] #[no_mangle] #[must_use] pub unsafe extern "C" fn pineappl_grid_new( @@ -890,6 +896,7 @@ pub unsafe extern "C" fn pineappl_grid_scale(grid: *mut Grid, factor: f64) { /// /// If `grid` does not point to a valid `Grid` object, for example when `grid` is the null pointer, /// this function is not safe to call. +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_split_channels` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_split_lumi(grid: *mut Grid) { let grid = unsafe { &mut *grid }; @@ -1005,6 +1012,7 @@ pub unsafe extern "C" fn pineappl_grid_scale_by_order( /// # Panics /// /// TODO +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_metadata` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_key_value( grid: *const Grid, @@ -1043,6 +1051,7 @@ pub unsafe extern "C" fn pineappl_grid_key_value( /// # Panics /// /// TODO +#[deprecated(since = "1.0.0", note = "use `pineappl_grid_set_metadata` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_grid_set_key_value( grid: *mut Grid, @@ -1153,6 +1162,7 @@ pub unsafe extern "C" fn pineappl_grid_write(grid: *const Grid, filename: *const /// The parameter `lumi` must point to a valid `Lumi` object created by `pineappl_lumi_new`. /// `pdg_id_pairs` must be an array with length `2 * combinations`, and `factors` with length of /// `combinations`. +#[deprecated(since = "1.0.0", note = "use `pineappl_channels_add` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_lumi_add( lumi: *mut Lumi, @@ -1183,6 +1193,7 @@ pub unsafe extern "C" fn pineappl_lumi_add( /// /// The parameter `lumi` must point to a valid `Lumi` object created by `pineappl_lumi_new` or /// `pineappl_grid_lumi`. +#[deprecated(since = "1.0.0", note = "use `pineappl_channels_combinations` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_lumi_combinations(lumi: *const Lumi, entry: usize) -> usize { let lumi = unsafe { &*lumi }; @@ -1196,6 +1207,7 @@ pub unsafe extern "C" fn pineappl_lumi_combinations(lumi: *const Lumi, entry: us /// /// The parameter `lumi` must point to a valid `Lumi` object created by `pineappl_lumi_new` or /// `pineappl_grid_lumi`. +#[deprecated(since = "1.0.0", note = "use `pineappl_channels_count` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_lumi_count(lumi: *const Lumi) -> usize { let lumi = unsafe { &*lumi }; @@ -1204,6 +1216,7 @@ pub unsafe extern "C" fn pineappl_lumi_count(lumi: *const Lumi) -> usize { } /// Delete luminosity function previously created with `pineappl_lumi_new`. +#[deprecated(since = "1.0.0", note = "use `pineappl_channels_delete` instead")] #[no_mangle] #[allow(unused_variables)] pub extern "C" fn pineappl_lumi_delete(lumi: Option>) {} @@ -1217,6 +1230,7 @@ pub extern "C" fn pineappl_lumi_delete(lumi: Option>) {} /// `pineappl_grid_lumi`. The parameter `factors` must point to an array as long as the size /// returned by `pineappl_lumi_combinations` and `pdg_ids` must point to an array that is twice as /// long. +#[deprecated(since = "1.0.0", note = "use `pineappl_channels_entry` instead")] #[no_mangle] pub unsafe extern "C" fn pineappl_lumi_entry( lumi: *const Lumi, @@ -1243,6 +1257,7 @@ pub unsafe extern "C" fn pineappl_lumi_entry( /// Creates a new luminosity function and returns a pointer to it. If no longer needed, the object /// should be deleted using `pineappl_lumi_delete`. +#[deprecated(since = "1.0.0", note = "use `pineappl_channels_new` instead")] #[no_mangle] #[must_use] pub extern "C" fn pineappl_lumi_new() -> Box { @@ -1260,6 +1275,7 @@ pub struct KeyVal { } /// Delete the previously created object pointed to by `key_vals`. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] #[allow(unused_variables)] pub extern "C" fn pineappl_keyval_delete(key_vals: Option>) {} @@ -1270,6 +1286,7 @@ pub extern "C" fn pineappl_keyval_delete(key_vals: Option>) {} /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] #[must_use] pub unsafe extern "C" fn pineappl_keyval_bool(key_vals: *const KeyVal, key: *const c_char) -> bool { @@ -1285,6 +1302,7 @@ pub unsafe extern "C" fn pineappl_keyval_bool(key_vals: *const KeyVal, key: *con /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] #[must_use] pub unsafe extern "C" fn pineappl_keyval_double( @@ -1303,6 +1321,7 @@ pub unsafe extern "C" fn pineappl_keyval_double( /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] #[must_use] pub unsafe extern "C" fn pineappl_keyval_int(key_vals: *const KeyVal, key: *const c_char) -> i32 { @@ -1318,6 +1337,7 @@ pub unsafe extern "C" fn pineappl_keyval_int(key_vals: *const KeyVal, key: *cons /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] #[must_use] pub unsafe extern "C" fn pineappl_keyval_string( @@ -1331,6 +1351,7 @@ pub unsafe extern "C" fn pineappl_keyval_string( } /// Return a pointer to newly-created `pineappl_keyval` object. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] #[must_use] pub extern "C" fn pineappl_keyval_new() -> Box { @@ -1343,6 +1364,7 @@ pub extern "C" fn pineappl_keyval_new() -> Box { /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] pub unsafe extern "C" fn pineappl_keyval_set_bool( key_vals: *mut KeyVal, @@ -1363,6 +1385,7 @@ pub unsafe extern "C" fn pineappl_keyval_set_bool( /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] pub unsafe extern "C" fn pineappl_keyval_set_double( key_vals: *mut KeyVal, @@ -1383,6 +1406,7 @@ pub unsafe extern "C" fn pineappl_keyval_set_double( /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] pub unsafe extern "C" fn pineappl_keyval_set_int( key_vals: *mut KeyVal, @@ -1403,6 +1427,7 @@ pub unsafe extern "C" fn pineappl_keyval_set_int( /// /// The parameter `key_vals` must point to a valid `KeyVal` object created by /// `pineappl_keyval_new`. `key` must be a valid C string. +#[deprecated(since = "1.0.0", note = "")] #[no_mangle] pub unsafe extern "C" fn pineappl_keyval_set_string( key_vals: *mut KeyVal, @@ -1435,40 +1460,40 @@ pub unsafe extern "C" fn pineappl_string_delete(string: *mut c_char) { // Here starts the generalized C-API interface. /// Type for defining a Channel function. -#[derive(Default)] -pub struct Channels(Vec); +#[derive(Clone)] +pub struct Channels { + channels: Vec, + convolutions: usize, +} /// Type for defining the interpolation object #[repr(C)] -pub struct InterpTuples { - node_min: f64, - node_max: f64, - nb_nodes: usize, - interp_degree: usize, - reweighting_method: ReweightMeth, - mapping: Map, - interpolation_method: InterpMeth, -} - -#[must_use] -fn construct_interpolation(interp: &InterpTuples) -> Interp { - Interp::new( - interp.node_min, - interp.node_max, - interp.nb_nodes, - interp.interp_degree, - interp.reweighting_method, - interp.mapping, - interp.interpolation_method, - ) +pub struct Interp { + /// TODO + pub min: f64, + /// TODO + pub max: f64, + /// TODO + pub nodes: usize, + /// TODO + pub order: usize, + /// TODO + pub reweight: ReweightMeth, + /// TODO + pub map: Map, + /// TODO + pub interp_meth: InterpMeth, } /// An exact duplicate of `pineappl_lumi_new` to make naming (lumi -> channel) consistent. /// should be deleted using `pineappl_channels_delete`. #[no_mangle] #[must_use] -pub extern "C" fn pineappl_channels_new() -> Box { - Box::default() +pub extern "C" fn pineappl_channels_new(convolutions: usize) -> Box { + Box::new(Channels { + channels: Vec::new(), + convolutions, + }) } /// Adds a generalized linear combination of initial states to the Luminosity. @@ -1484,24 +1509,26 @@ pub extern "C" fn pineappl_channels_new() -> Box { pub unsafe extern "C" fn pineappl_channels_add( channels: *mut Channels, combinations: usize, - nb_convolutions: usize, pdg_id_combinations: *const i32, factors: *const f64, ) { - let channels = unsafe { &mut *channels }; + let &mut Channels { + ref mut channels, + convolutions, + } = unsafe { &mut *channels }; let pdg_id_pairs = - unsafe { slice::from_raw_parts(pdg_id_combinations, nb_convolutions * combinations) }; + unsafe { slice::from_raw_parts(pdg_id_combinations, convolutions * combinations) }; let factors = if factors.is_null() { vec![1.0; combinations] } else { unsafe { slice::from_raw_parts(factors, combinations) }.to_vec() }; - channels.0.push(Channel::new( + channels.push(Channel::new( pdg_id_pairs - .chunks(nb_convolutions) + .chunks(convolutions) .zip(factors) - .map(|x| ((0..nb_convolutions).map(|i| x.0[i]).collect(), x.1)) + .map(|x| ((0..convolutions).map(|i| x.0[i]).collect(), x.1)) .collect(), )); } @@ -1516,7 +1543,10 @@ pub unsafe extern "C" fn pineappl_channels_add( pub unsafe extern "C" fn pineappl_grid_channels(grid: *const Grid) -> Box { let grid = unsafe { &*grid }; - Box::new(Channels(grid.channels().to_vec())) + Box::new(Channels { + channels: grid.channels().to_vec(), + convolutions: grid.convolutions().len(), + }) } /// An exact duplicate of `pineappl_lumi_count` to make naming (lumi -> channel) consistent. @@ -1527,9 +1557,9 @@ pub unsafe extern "C" fn pineappl_grid_channels(grid: *const Grid) -> Box usize { - let channels = unsafe { &*channels }; + let Channels { channels, .. } = unsafe { &*channels }; - channels.0.len() + channels.len() } /// An exact duplicate of `pineappl_lumi_combinations` to make naming (lumi -> channel) consistent. @@ -1543,9 +1573,9 @@ pub unsafe extern "C" fn pineappl_channels_combinations( channels: *const Channels, entry: usize, ) -> usize { - let channels = unsafe { &*channels }; + let Channels { channels, .. } = unsafe { &*channels }; - channels.0[entry].entry().len() + channels[entry].entry().len() } /// An exact duplicate of `pineappl_lumi_delete` to make naming (lumi -> channel) consistent. @@ -1580,30 +1610,31 @@ pub extern "C" fn pineappl_channels_delete(channels: Option>) {} /// `0` -> `ScaleFuncForm::NoScale`, ..., `n` -> `ScaleFuncForm::Scale(n - 1)`. /// /// # Safety +/// /// TODO /// /// # Panics +/// /// TODO #[no_mangle] #[must_use] pub unsafe extern "C" fn pineappl_grid_new2( - pid_basis: PidBasis, - channels: *const Channels, - orders: usize, - order_params: *const u8, bins: usize, bin_limits: *const f64, - nb_convolutions: usize, - convolution_types: *const ConvType, - pdg_ids: *const c_int, + orders: usize, + order_params: *const u8, + channels: *const Channels, + pid_basis: PidBasis, + convolutions: *const Conv, + interpolations: usize, + interps: *const Interp, kinematics: *const Kinematics, - interpolations: *const InterpTuples, - mu_scales: *const usize, + scales: *const ScaleFuncForm, ) -> Box { - // Luminosity channels - let channels = unsafe { &*channels }; - - // Perturbative orders + let bins = BinsWithFillLimits::from_fill_limits( + unsafe { slice::from_raw_parts(bin_limits, bins + 1) }.to_vec(), + ) + .unwrap(); let order_params = unsafe { slice::from_raw_parts(order_params, 5 * orders) }; let orders: Vec<_> = order_params .chunks(5) @@ -1615,52 +1646,48 @@ pub unsafe extern "C" fn pineappl_grid_new2( logxia: s[4], }) .collect(); + let Channels { + channels, + convolutions: nb_convolutions, + } = unsafe { &*channels }.clone(); - let bins = BinsWithFillLimits::from_fill_limits( - unsafe { slice::from_raw_parts(bin_limits, bins + 1) }.to_vec(), - ) - .unwrap(); - - // Construct the convolution objects - let convolution_types = - unsafe { slice::from_raw_parts(convolution_types, nb_convolutions).to_vec() }; - let pdg_ids = unsafe { slice::from_raw_parts(pdg_ids, nb_convolutions).to_vec() }; - let convolutions = izip!(convolution_types.iter(), pdg_ids.iter()) - .map(|(&conv, &pdg_value)| Conv::new(conv, pdg_value)) - .collect(); + let convolutions = unsafe { slice::from_raw_parts(convolutions, nb_convolutions) }.to_vec(); // Grid interpolations - let interp_slices = unsafe { std::slice::from_raw_parts(interpolations, nb_convolutions + 1) }; - let interp_vecs: Vec = interp_slices.iter().map(construct_interpolation).collect(); - - // Construct the kinematic variables - let kinematics = unsafe { slice::from_raw_parts(kinematics, interp_vecs.len()).to_vec() }; - - // Scales. An array containing the values of {ren, fac, frg} - let mu_scales = unsafe { std::slice::from_raw_parts(mu_scales, 3) }; - let mu_scales_vec: Vec = mu_scales + let interp_slices = unsafe { std::slice::from_raw_parts(interps, interpolations) }; + let interp_vecs: Vec<_> = interp_slices .iter() - .map(|&scale| { - if scale == 0 { - ScaleFuncForm::NoScale - } else { - ScaleFuncForm::Scale(scale - 1) - } + .map(|interp| { + InterpMain::new( + interp.min, + interp.max, + interp.nodes, + interp.order, + interp.reweight, + interp.map, + interp.interp_meth, + ) }) .collect(); + // Construct the kinematic variables + let kinematics = unsafe { slice::from_raw_parts(kinematics, interp_vecs.len()) }.to_vec(); + + // Scales. An array containing the values of `ScaleFuncForm` objects + let mu_scales = unsafe { std::slice::from_raw_parts(scales, 3) }; + Box::new(Grid::new( bins, orders, - channels.0.clone(), + channels, pid_basis, convolutions, interp_vecs, kinematics, Scales { - ren: mu_scales_vec[0].clone(), - fac: mu_scales_vec[1].clone(), - frg: mu_scales_vec[2].clone(), + ren: mu_scales[0].clone(), + fac: mu_scales[1].clone(), + frg: mu_scales[2].clone(), }, )) } @@ -1776,11 +1803,11 @@ pub unsafe extern "C" fn pineappl_channels_entry( pdg_ids: *mut i32, factors: *mut f64, ) { - let channels = unsafe { &*channels }; - let entry = channels.0[entry].entry(); - // if the channel has no entries we assume no convolutions, which is OK we don't copy anything - // in this case - let convolutions = entry.get(0).map_or(0, |x| x.0.len()); + let Channels { + channels, + convolutions, + } = unsafe { &*channels }; + let entry = channels[entry].entry(); let pdg_ids = unsafe { slice::from_raw_parts_mut(pdg_ids, convolutions * entry.len()) }; let factors = unsafe { slice::from_raw_parts_mut(factors, entry.len()) };