Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:23:23

0001 // FragmentationFlavZpT.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2025 Torbjorn Sjostrand.
0003 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
0004 // Please respect the MCnet Guidelines, see GUIDELINES for details.
0005 
0006 // This file contains helper classes for fragmentation.
0007 // StringFlav is used to select quark and hadron flavours.
0008 // StringPT is used to select transverse momenta.
0009 // StringZ is used to sample the fragmentation function f(z).
0010 
0011 #ifndef Pythia8_FragmentationFlavZpT_H
0012 #define Pythia8_FragmentationFlavZpT_H
0013 
0014 #include "Pythia8/Basics.h"
0015 #include "Pythia8/MathTools.h"
0016 #include "Pythia8/ParticleData.h"
0017 #include "Pythia8/PhysicsBase.h"
0018 #include "Pythia8/PythiaStdlib.h"
0019 #include "Pythia8/Settings.h"
0020 
0021 namespace Pythia8 {
0022 
0023 //==========================================================================
0024 
0025 // The FlavContainer class is a simple container for flavour,
0026 // including the extra properties needed for popcorn baryon handling.
0027 // id = current flavour.
0028 // rank = current rank; 0 for endpoint flavour and then increase by 1.
0029 // nPop = number of popcorn mesons yet to be produced (1 or 0).
0030 // idPop = (absolute sign of) popcorn quark, shared between B and Bbar.
0031 // idVtx = (absolute sign of) vertex (= non-shared) quark in diquark.
0032 
0033 class FlavContainer {
0034 
0035 public:
0036 
0037   // Constructor.
0038   FlavContainer(int idIn = 0, int rankIn = 0, int nPopIn = 0,
0039     int idPopIn = 0, int idVtxIn = 0) : id(idIn), rank(rankIn),
0040     nPop(nPopIn), idPop(idPopIn), idVtx(idVtxIn) {}
0041 
0042   // Copy constructor.
0043   FlavContainer(const FlavContainer& flav) {
0044     id = flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
0045     idVtx = flav.idVtx;}
0046 
0047   // Overloaded equal operator.
0048   FlavContainer& operator=(const FlavContainer& flav) { if (this != &flav) {
0049     id = flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
0050     idVtx = flav.idVtx; } return *this; }
0051 
0052   // Invert flavour.
0053   FlavContainer& anti() {id = -id; return *this;}
0054 
0055   // Read in a container into another, without/with id sign flip.
0056   FlavContainer& copy(const FlavContainer& flav) { if (this != &flav) {
0057     id = flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
0058     idVtx = flav.idVtx; } return *this; }
0059   FlavContainer& anti(const FlavContainer& flav) { if (this != &flav) {
0060     id = -flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
0061     idVtx = flav.idVtx; } return *this; }
0062 
0063   // Check whether is diquark.
0064   bool isDiquark() {int idAbs = abs(id);
0065     return (idAbs > 1000 && idAbs < 10000 && (idAbs/10)%10 == 0);}
0066 
0067   // Stored properties.
0068   int id, rank, nPop, idPop, idVtx;
0069 
0070 };
0071 
0072 //==========================================================================
0073 
0074 // The StringFlav class is used to select quark and hadron flavours.
0075 
0076 class StringFlav : public PhysicsBase {
0077 
0078 public:
0079 
0080   // Constructor.
0081   StringFlav() :
0082     suppressLeadingB(),
0083     mT2suppression(), useWidthPre(), probQQtoQ(), probStoUD(), probSQtoQQ(),
0084     probQQ1toQQ0(), probQandQQ(), probQandS(), probQandSinQQ(), probQQ1corr(),
0085     probQQ1corrInv(), probQQ1norm(), probQQ1join(), mesonRate(),
0086     mesonRateSum(), mesonMix1(), mesonMix2(), etaSup(), etaPrimeSup(),
0087     decupletSup(), baryonCGSum(), baryonCGMax(), popcornRate(), popcornSpair(),
0088     popcornSmeson(), barCGMax(), scbBM(), popFrac(), popS(), dWT(),
0089     lightLeadingBSup(), heavyLeadingBSup(), probStoUDSav(), probQQtoQSav(),
0090     probSQtoQQSav(), probQQ1toQQ0Sav(), alphaQQSav(), sigmaHad(),
0091     widthPreStrange(), widthPreDiquark(), thermalModel(), mesonNonetL1(),
0092     temperature(), tempPreFactor(), nNewQuark(), mesMixRate1(), mesMixRate2(),
0093     mesMixRate3(), baryonOctWeight(), baryonDecWeight(), closePacking(),
0094     doEnhanceDiquark(), enhanceStrange(), enhancePT(), enhanceDiquark(),
0095     exponentMPI(), exponentNSP(), hadronIDwin(0), idNewWin(0),
0096     hadronMassWin(-1.0) {}
0097 
0098   // Destructor.
0099   virtual ~StringFlav() {}
0100 
0101   // Initialize data members.
0102   virtual void init();
0103 
0104   // Initialise parameters when using close packing.
0105   virtual void init(double kappaModifier, double strangeJunc,
0106     double probQQmod);
0107 
0108   // Pick a light d, u or s quark according to fixed ratios.
0109   int pickLightQ() { double rndmFlav = probQandS * rndmPtr->flat();
0110     if (rndmFlav < 1.) return 1;
0111     if (rndmFlav < 2.) return 2;
0112     return 3; }
0113 
0114   // Pick a new flavour (including diquarks) given an incoming one,
0115   // either by old standard Gaussian or new alternative exponential.
0116   virtual FlavContainer pick(FlavContainer& flavOld, double pT = -1.0,
0117     double kappaModifier = -1.0, bool allowPop = true) {
0118     hadronIDwin = 0; idNewWin = 0; hadronMassWin = -1.0;
0119     if ( (thermalModel || mT2suppression) && (pT >= 0.0) )
0120       return pickThermal(flavOld, pT, kappaModifier);
0121     return pickGauss(flavOld, allowPop); }
0122   virtual FlavContainer pickGauss(FlavContainer& flavOld,
0123     bool allowPop = true);
0124   virtual FlavContainer pickThermal(FlavContainer& flavOld,
0125     double pT, double kappaModifier);
0126 
0127   // Combine two flavours (including diquarks) to produce a hadron.
0128   virtual int combine(FlavContainer& flav1, FlavContainer& flav2);
0129 
0130   // Ditto, simplified input argument for simple configurations.
0131   virtual int combineId( int id1, int id2, bool keepTrying = true) {
0132     FlavContainer flag1(id1); FlavContainer flag2(id2);
0133     for (int i = 0; i < 100; ++i) { int idNew = combine( flag1, flag2);
0134       if (idNew != 0 || !keepTrying) return idNew;} return 0;}
0135 
0136   // Combine three (di-) quark flavours into two hadrons.
0137   virtual pair<int,int> combineDiquarkJunction(int id1, int id2, int id3);
0138 
0139   // Combine two flavours to produce a hadron with lowest possible mass.
0140   virtual int combineToLightest( int id1, int id2);
0141 
0142   // Lightest flavour-neutral meson.
0143   virtual int idLightestNeutralMeson() { return 111; }
0144 
0145   // Return chosen hadron in case of thermal model.
0146   virtual int getHadronIDwin() { return hadronIDwin; }
0147 
0148   // Combine two flavours into hadron for last two remaining flavours
0149   // for thermal model.
0150   virtual int combineLastThermal(FlavContainer& flav1, FlavContainer& flav2,
0151     double pT, double kappaModifier);
0152 
0153   // General function, decides whether to just return the hadron id
0154   // if thermal model was use or whether to combine the two flavours.
0155   virtual int getHadronID(FlavContainer& flav1, FlavContainer& flav2,
0156     double pT = -1.0, double kappaModifier = -1.0, bool finalTwo = false) {
0157     if (finalTwo) return ((thermalModel || mT2suppression) ?
0158       combineLastThermal(flav1, flav2, pT, kappaModifier)
0159       : combine(flav1, flav2));
0160     if ((thermalModel || mT2suppression)&& (hadronIDwin != 0)
0161       && (idNewWin != 0)) return getHadronIDwin();
0162     return combine(flav1, flav2); }
0163 
0164   // Return hadron mass. Used one if present, pick otherwise.
0165   virtual double getHadronMassWin(int idHad) { return
0166     ((hadronMassWin < 0.0) ? particleDataPtr->mSel(idHad) : hadronMassWin); }
0167 
0168   // Assign popcorn quark inside an original (= rank 0) diquark.
0169   void assignPopQ(FlavContainer& flav);
0170 
0171   // Combine two quarks to produce a diquark.
0172   int makeDiquark(int id1, int id2, int idHad = 0);
0173 
0174   // Check if quark-diquark combination should be added. If so add.
0175   void addQuarkDiquark(vector< pair<int,int> >& quarkCombis,
0176     int qID, int diqID, int hadronID) {
0177     bool allowed = true;
0178     for (int iCombi = 0; iCombi < int(quarkCombis.size()); iCombi++)
0179       if ( (qID   == quarkCombis[iCombi].first ) &&
0180            (diqID == quarkCombis[iCombi].second) ) allowed = false;
0181     if (allowed) quarkCombis.push_back( (hadronID > 0) ?
0182       make_pair( qID,  diqID) : make_pair(-qID, -diqID) ); }
0183 
0184   // Get spin counter for mesons.
0185   int getMesonSpinCounter(int hadronID) { hadronID = abs(hadronID);
0186     int j = (hadronID % 10);
0187     if (hadronID <  1000) return ((j==1) ? 0 : ( (j==3) ? 1 : 5 ));
0188     if (hadronID < 20000) return ((j==1) ? 3 : 2);
0189     if (hadronID > 20000) return 4;
0190     return -1; }
0191 
0192   // Get the flavour and spin ratios calculated from the diquark weights.
0193   // i: (0) q -> B B, (1) q -> B M B, (2) qq -> M B
0194   // j: (0) s/u popcorn ratio, (1/2) s/u ratio for vertex quark if popcorn
0195   //    quark is u/d or s, (3) q/q' vertex quark ratio if popcorn quark is
0196   //    light and = q, (4/5/6) (spin 1)/(spin 0) ratio for su, us and ud
0197   double getFlavourSpinRatios(int i, int j) {
0198     return (i < 3 && j < 7) ? dWT[i][j] : -1.0;}
0199 
0200 protected:
0201 
0202   // Initialise derived parameters.
0203   virtual void initDerived();
0204 
0205   // Constants: could only be changed in the code itself.
0206   static const int    mesonMultipletCode[6];
0207   static const double baryonCGOct[6], baryonCGDec[6];
0208 
0209   // Settings for Gaussian model.
0210   bool   suppressLeadingB, mT2suppression, useWidthPre;
0211   double probQQtoQ, probStoUD, probSQtoQQ, probQQ1toQQ0, probQandQQ,
0212          probQandS, probQandSinQQ, probQQ1corr, probQQ1corrInv, probQQ1norm,
0213          probQQ1join[4], mesonRate[4][6], mesonRateSum[4], mesonMix1[2][6],
0214          mesonMix2[2][6], etaSup, etaPrimeSup, decupletSup, baryonCGSum[6],
0215          baryonCGMax[6], popcornRate, popcornSpair, popcornSmeson, barCGMax[8],
0216          scbBM[3], popFrac, popS[3], dWT[3][7], lightLeadingBSup,
0217          heavyLeadingBSup;
0218   bool   qqKappa;
0219   double probStoUDSav, probQQtoQSav, probSQtoQQSav, probQQ1toQQ0Sav,
0220          alphaQQSav, sigmaHad, widthPreStrange, widthPreDiquark;
0221 
0222   // Settings for thermal model.
0223   bool   thermalModel, mesonNonetL1;
0224   double temperature, tempPreFactor;
0225   int    nNewQuark;
0226   double mesMixRate1[2][6], mesMixRate2[2][6], mesMixRate3[2][6];
0227   double baryonOctWeight[6][6][6][2], baryonDecWeight[6][6][6][2];
0228 
0229   // Settings used by both models.
0230   bool   closePacking, doEnhanceDiquark;
0231   double enhanceStrange, enhancePT, enhanceDiquark, exponentMPI, exponentNSP;
0232 
0233   // Key = hadron id, value = list of constituent ids.
0234   map< int, vector< pair<int,int> > > hadronConstIDs;
0235   // Key = initial (di)quark id, value = list of possible hadron ids
0236   //                                     + nr in hadronConstIDs.
0237   map< int, vector< pair<int,int> > > possibleHadrons;
0238   // Key = initial (di)quark id, value = prefactor to multiply rate.
0239   map< int, vector<double> > possibleRatePrefacs;
0240   // Similar, but for combining the last two (di)quarks. Key = (di)quark pair.
0241   map< pair<int,int>, vector< pair<int,int> > > possibleHadronsLast;
0242   map< pair<int,int>, vector<double> > possibleRatePrefacsLast;
0243 
0244   // Selection in thermal model.
0245   int    hadronIDwin, idNewWin;
0246   double hadronMassWin;
0247 
0248   // Fragmentation weights container.
0249   WeightsFragmentation* wgtsPtr{};
0250 
0251 };
0252 
0253 //==========================================================================
0254 
0255 // Functions for unnormalised, <z>, and RMSD(z) of Lund FF. The two latter
0256 // return negative values in case of failure.
0257 
0258 double LundFFRaw(double z, double a, double b, double c, double mT2);
0259 
0260 double LundFFAvg(double a, double b, double mT2, double tol);
0261 
0262 double LundFFRms(double a, double b, double mT2, double tol);
0263 
0264 //==========================================================================
0265 
0266 // The StringZ class is used to sample the fragmentation function f(z).
0267 
0268 class StringZ : public PhysicsBase {
0269 
0270 public:
0271 
0272   // Constructor.
0273   StringZ() : useNonStandC(), useNonStandB(), useNonStandH(), usePetersonC(),
0274     usePetersonB(), usePetersonH(), useOldAExtra(), mc2(), mb2(),
0275     aLund(), bLund(), aExtraSQuark(), aExtraDiquark(), rFactC(),
0276     rFactB(), rFactH(), aNonC(), aNonB(), aNonH(), bNonC(), bNonB(),
0277     bNonH(), epsilonC(), epsilonB(), epsilonH(), stopM(), stopNF(),
0278     stopS() {}
0279 
0280   // Destructor.
0281   virtual ~StringZ() {}
0282 
0283   // Initialize data members.
0284   virtual bool init();
0285 
0286   // Fragmentation function: top-level to determine parameters.
0287   virtual double zFrag( int idOld, int idNew = 0, double mT2 = 1.);
0288 
0289   // Fragmentation function: select z according to provided parameters.
0290   virtual double zLund( double a, double b, double c = 1.,
0291     double head = 1., double bNow = 0., int idFrag = 0,
0292     bool isOldSQuark = false, bool isNewSQuark = false,
0293     bool isOldDiquark = false, bool isNewDiquark = false);
0294   virtual double zPeterson( double epsilon);
0295   virtual double zLundMax( double a, double b, double c = 1.);
0296 
0297   // Parameters for stopping in the middle; overloaded for Hidden Valley.
0298   virtual double stopMass() {return stopM;}
0299   virtual double stopNewFlav() {return stopNF;}
0300   virtual double stopSmear() {return stopS;}
0301 
0302   // a and b fragmentation parameters needed in some operations.
0303   virtual double aAreaLund() {return aLund;}
0304   virtual double bAreaLund() {return bLund;}
0305 
0306   // Method to derive both a and b parameters (from <z> and RMSD(z)).
0307   bool deriveABLund( bool derivaA = false, bool deriveAExtraDiquark = false,
0308                      bool deriveAExtraSQuark = false);
0309   // Method to derive bLund from <z> (for fixed a and reference mT2).
0310   double deriveBLund( double avgZ, double a, double mT2ref);
0311 
0312  protected:
0313 
0314   // Constants: could only be changed in the code itself.
0315   static const double CFROMUNITY, AFROMZERO, AFROMC, EXPMAX;
0316 
0317   // Initialization data, to be read from Settings.
0318   bool   useNonStandC, useNonStandB, useNonStandH,
0319          usePetersonC, usePetersonB, usePetersonH, useOldAExtra;
0320   double mc2, mb2, aLund, bLund, aExtraSQuark, aExtraDiquark, rFactC,
0321          rFactB, rFactH, aNonC, aNonB, aNonH, bNonC, bNonB, bNonH,
0322          epsilonC, epsilonB, epsilonH, stopM, stopNF, stopS;
0323 
0324   // Fragmentation weights container.
0325   WeightsFragmentation* wgtsPtr{};
0326 
0327 };
0328 
0329 //==========================================================================
0330 
0331 // The StringPT class is used to select select transverse momenta.
0332 
0333 class StringPT : public PhysicsBase {
0334 
0335 public:
0336 
0337   // Constructor.
0338   StringPT() : useWidthPre(), sigmaQ(), enhancedFraction(), enhancedWidth(),
0339     sigma2Had(), widthPreStrange(), widthPreDiquark(),
0340     thermalModel(), temperature(), tempPreFactor(), fracSmallX(),
0341     closePacking(), enhancePT(), exponentMPI(), exponentNSP() {}
0342 
0343   // Destructor.
0344   virtual ~StringPT() {}
0345 
0346   // Initialize data members.
0347   virtual void init();
0348 
0349   // General function, return px and py as a pair in the same call
0350   // in either model.
0351   pair<double, double>  pxy(int idIn, double kappaModifier = -1.0) {
0352     return (thermalModel ? pxyThermal(idIn, kappaModifier) :
0353     pxyGauss(idIn, kappaModifier)); }
0354   pair<double, double>  pxyGauss(int idIn = 0, double kappaModifier = -1.0);
0355   pair<double, double>  pxyThermal(int idIn, double kappaModifier = -1.0);
0356 
0357   // Gaussian suppression of given pT2; used in MiniStringFragmentation.
0358   double suppressPT2(double pT2) { return (thermalModel ?
0359     exp(-sqrt(pT2)/temperature) : exp(-pT2/sigma2Had)); }
0360 
0361 protected:
0362 
0363   // Constants: could only be changed in the code itself.
0364   static const double SIGMAMIN;
0365 
0366   // Initialization data, to be read from Settings.
0367   // Gaussian model.
0368   bool   useWidthPre;
0369   double sigmaQ, enhancedFraction, enhancedWidth, sigma2Had,
0370          widthPreStrange, widthPreDiquark;
0371   // Thermal model.
0372   bool   thermalModel;
0373   double temperature, tempPreFactor, fracSmallX;
0374   // Both.
0375   bool   closePacking;
0376   double enhancePT, exponentMPI, exponentNSP;
0377 
0378 private:
0379 
0380   // Evaluate Bessel function K_{1/4}(x).
0381   double BesselK14(double x);
0382 
0383   // Fragmentation weights container.
0384   WeightsFragmentation* wgtsPtr{};
0385 
0386 };
0387 
0388 //==========================================================================
0389 
0390 } // end namespace Pythia8
0391 
0392 #endif // Pythia8_FragmentationFlavZpT_H