Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:17:14

0001 // APFEL++ 2017
0002 
0003 #pragma once
0004 
0005 #include "apfel/doubleoperator.h"
0006 #include "apfel/doubledistribution.h"
0007 #include "apfel/distribution.h"
0008 #include "apfel/grid.h"
0009 
0010 #include <functional>
0011 #include <map>
0012 #include <string>
0013 #include <vector>
0014 
0015 namespace apfel
0016 {
0017   /**
0018    * @brief Structure containing pre-computed DoubleOperator objects for
0019    * all SIDIS coefficient functions up to exact NNLO.
0020    *
0021    * Operators are organised in three maps by structure function type:
0022    * - @c FT: unpolarised transverse (= F<SUB>1</SUB>) operators
0023    * - @c FL: unpolarised longitudinal operators
0024    * - @c G1: longitudinally polarised G<SUB>1</SUB> operators
0025    *
0026    * Within each map, entries are keyed by the name of the corresponding
0027    * DoubleExpression (i.e. matching DoubleExpression::GetName()), e.g.:
0028    * - @c "DoubleIdentity"  → LO (FT and G1 only)
0029    * - @c "C1TQ2Q"          → NLO FT qq channel
0030    * - @c "C2TQ2QNS_nf3"    → NNLO FT non-singlet at nf = 3
0031    * - @c "DC2Q2G_nf5"      → NNLO G1 gluon-in-quark at nf = 5
0032    *
0033    * @note The DoubleOperator objects hold references to the Grid objects
0034    * passed to InitializeSidisObjects(). Those grids must remain alive
0035    * for the lifetime of this structure.
0036    */
0037   struct SidisNNLOObjects
0038   {
0039     std::map<std::string, DoubleOperator> FT;
0040     std::map<std::string, DoubleOperator> FL;
0041     std::map<std::string, DoubleOperator> G1;
0042   };
0043 
0044   /**
0045    * @brief Initialises all SIDIS DoubleOperator objects (LO + NLO + exact NNLO)
0046    * for the unpolarised (FT, FL) and polarised (G1) structure functions.
0047    *
0048    * This is the exact NNLO implementation. It uses the DoubleExpression
0049    * subclasses from sidiscoefficientfunctionsunp.h and sidiscoefficientfunctionspol.h
0050    * directly.
0051    *
0052    * Coefficient function references:
0053    * - NLO:  hep-ph/9711387 Appendix C
0054    * - NNLO unpolarised:  arXiv:2401.16281
0055    * - NNLO polarised:    arXiv:2404.08597
0056    *
0057    * @param gx: x-space grid (must outlive the returned object)
0058    * @param gz: z-space grid (must outlive the returned object)
0059    * @param Thresholds: heavy-quark thresholds determining the active-nf range
0060    * @param IntEps: integration accuracy for DoubleOperator construction (default: 1e-3)
0061    * @return SidisNNLOObjects with all operators indexed by channel name
0062    */
0063   SidisNNLOObjects InitializeSidisObjects(Grid                const& gx,
0064                                           Grid                const& gz,
0065                                           std::vector<double> const& Thresholds,
0066                                           double              const& IntEps = 1e-3);
0067 
0068   /**
0069    * @brief Builds the unpolarised transverse (F<SUB>T</SUB> = F<SUB>1</SUB>) SIDIS
0070    * cross-section function from pre-computed operators.
0071    *
0072    * The returned function maps a scale Q to a DoubleDistribution f(x, z) such
0073    * that the physical cross section is obtained via
0074    * @code
0075    *   auto FT = BuildSidisUnpFT(obj, InPDFs, InFFs, Alphas, Thresholds);
0076    *   double xsec = FT(Q).Evaluate1(x).Integrate(zmin, zmax);
0077    * @endcode
0078    * The 1/(xz) kinematic prefactor is included.
0079    *
0080    * @param obj: pre-computed operators from InitializeSidisObjects (must outlive the returned function)
0081    * @param InPDFs: unpolarised PDFs as xf(x, Q), mapping flavour id to value
0082    * @param InFFs: fragmentation functions as zD(z, Q), mapping flavour id to value
0083    * @param Alphas: strong coupling α<SUB>s</SUB>(Q)
0084    * @param Thresholds: heavy-quark thresholds (used to determine nf at each Q)
0085    * @param PerturbativeOrder: 0 = LO, 1 = NLO, 2 = NNLO (default: 2); only used when channel = -1
0086    * @param channel: partonic channel selector (default: -1 = full sum controlled by PerturbativeOrder).
0087    *   Individual channels follow the benchmark convention:
0088    *   0 = LO ns; 1 = LO+NLO ns; 2 = NLO qg; 3 = NLO gq;
0089    *   4 = ns+ps through NNLO; 5 = qg through NNLO; 6 = gq through NNLO;
0090    *   7 = NNLO gg; 8 = NNLO qbq; 9 = NNLO qpq.
0091    * @return function Q → F<SUB>T</SUB> DoubleDistribution
0092    */
0093   std::function<DoubleDistribution(double const&)> BuildSidisUnpFT(
0094     SidisNNLOObjects                                                          const& obj,
0095     std::function<std::map<int, double>(double const&, double const&)> const& InPDFs,
0096     std::function<std::map<int, double>(double const&, double const&)> const& InFFs,
0097     std::function<double(double const&)>                               const& Alphas,
0098     std::vector<double>                                                const& Thresholds,
0099     int                                                                const& PerturbativeOrder = 2,
0100     int                                                                const& channel = -1);
0101 
0102   /**
0103    * @brief Builds the unpolarised longitudinal (F<SUB>L</SUB>) SIDIS
0104    * cross-section function from pre-computed operators.
0105    *
0106    * Identical API to BuildSidisUnpFT but for F<SUB>L</SUB>.
0107    * F<SUB>L</SUB> has no LO contribution; PerturbativeOrder = 0 returns zero.
0108    *
0109    * @param obj: pre-computed operators from InitializeSidisObjects (must outlive the returned function)
0110    * @param InPDFs: unpolarised PDFs as xf(x, Q)
0111    * @param InFFs: fragmentation functions as zD(z, Q)
0112    * @param Alphas: strong coupling α<SUB>s</SUB>(Q)
0113    * @param Thresholds: heavy-quark thresholds
0114    * @param PerturbativeOrder: 0 = 0 (no LO), 1 = NLO, 2 = NNLO (default: 2)
0115    * @return function Q → F<SUB>L</SUB> DoubleDistribution
0116    */
0117   std::function<DoubleDistribution(double const&)> BuildSidisUnpFL(
0118     SidisNNLOObjects                                                          const& obj,
0119     std::function<std::map<int, double>(double const&, double const&)> const& InPDFs,
0120     std::function<std::map<int, double>(double const&, double const&)> const& InFFs,
0121     std::function<double(double const&)>                               const& Alphas,
0122     std::vector<double>                                                const& Thresholds,
0123     int                                                                const& PerturbativeOrder = 2);
0124 
0125   /**
0126    * @brief Builds the longitudinally polarised G<SUB>1</SUB> SIDIS
0127    * cross-section function from pre-computed operators.
0128    *
0129    * Identical API to BuildSidisUnpFT but for G<SUB>1</SUB>.
0130    * @c InPDFs should provide the polarised (helicity) PDFs Δf(x, Q).
0131    *
0132    * @param obj: pre-computed operators from InitializeSidisObjects (must outlive the returned function)
0133    * @param InPDFs: polarised PDFs as xΔf(x, Q)
0134    * @param InFFs: fragmentation functions as zD(z, Q)
0135    * @param Alphas: strong coupling α<SUB>s</SUB>(Q)
0136    * @param Thresholds: heavy-quark thresholds
0137    * @param PerturbativeOrder: 0 = LO, 1 = NLO, 2 = NNLO (default: 2); only used when channel = -1
0138    * @param channel: partonic channel selector (default: -1 = full sum); see BuildSidisUnpFT for convention
0139    * @return function Q → G<SUB>1</SUB> DoubleDistribution
0140    */
0141   std::function<DoubleDistribution(double const&)> BuildSidisG1(
0142     SidisNNLOObjects                                                          const& obj,
0143     std::function<std::map<int, double>(double const&, double const&)> const& InPDFs,
0144     std::function<std::map<int, double>(double const&, double const&)> const& InFFs,
0145     std::function<double(double const&)>                               const& Alphas,
0146     std::vector<double>                                                const& Thresholds,
0147     int                                                                const& PerturbativeOrder = 2,
0148     int                                                                const& channel = -1);
0149 }