Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 09:06:37

0001 // ColourReconnection.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 // Header file for the Colour reconnection handling.
0007 // Reconnect the colours between the partons before hadronization.
0008 // It Contains the following classes:
0009 // ColourDipole, ColourParticle, ColourJunction, ColourReconnection.
0010 
0011 #ifndef Pythia8_ColourReconnection_H
0012 #define Pythia8_ColourReconnection_H
0013 
0014 #include "Pythia8/Basics.h"
0015 #include "Pythia8/BeamParticle.h"
0016 #include "Pythia8/Event.h"
0017 #include "Pythia8/FragmentationFlavZpT.h"
0018 #include "Pythia8/Info.h"
0019 #include "Pythia8/ParticleData.h"
0020 #include "Pythia8/StringFragmentation.h"
0021 #include "Pythia8/PartonDistributions.h"
0022 #include "Pythia8/PartonSystems.h"
0023 #include "Pythia8/PythiaStdlib.h"
0024 #include "Pythia8/Settings.h"
0025 #include "Pythia8/StringLength.h"
0026 #include "Pythia8/StringInteractions.h"
0027 
0028 namespace Pythia8 {
0029 
0030 //==========================================================================
0031 
0032 // Contain a single colour chain. It always start from a quark and goes to
0033 // an anti quark or from an anti-junction to at junction
0034 // (or possible combinations).
0035 
0036 class ColourDipole {
0037 
0038 public:
0039 
0040   // Constructor.
0041   ColourDipole( int colIn = 0, int iColIn = 0, int iAcolIn = 0,
0042     int colReconnectionIn = 0, bool isJunIn = false, bool isAntiJunIn = false,
0043     bool isActiveIn = true, bool isRealIn = false) : col(colIn), iCol(iColIn),
0044     iAcol(iAcolIn), colReconnection(colReconnectionIn), isJun(isJunIn),
0045     isAntiJun(isAntiJunIn),isActive(isActiveIn), isReal(isRealIn)
0046     {iColLeg = 0; iAcolLeg = 0; printed = false; p1p2 = 0.;}
0047 
0048   double mDip(Event & event) {
0049     if (isJun || isAntiJun) return 1E9;
0050     else return m(event[iCol].p(),event[iAcol].p());
0051   }
0052 
0053   // Members.
0054   int    col, iCol, iAcol, iColLeg, iAcolLeg, colReconnection;
0055   bool   isJun, isAntiJun, isActive, isReal, printed;
0056   weak_ptr<ColourDipole> leftDip{}, rightDip{};
0057   vector<weak_ptr<ColourDipole> > colDips, acolDips;
0058   double p1p2;
0059 
0060   // Information for caching dipole momentum.
0061   Pythia8::Vec4 dipoleMomentum;
0062   int ciCol{-1}, ciAcol{-1};
0063   bool pCalculated{false};
0064 
0065   // Printing function, mainly intended for debugging.
0066   void list() const;
0067   long index{0};
0068 
0069 };
0070 
0071 // Comparison operator by index for two dipole pointers.
0072 inline bool operator<(const ColourDipolePtr& d1, const ColourDipolePtr& d2) {
0073   return ( d1 && d2 ? d1->index < d2->index : !d1 );}
0074 
0075 //==========================================================================
0076 
0077 // Junction class. In addition to the normal junction class, also contains a
0078 // list of dipoles connected to it.
0079 
0080 class ColourJunction : public Junction {
0081 
0082 public:
0083 
0084   ColourJunction(const Junction& ju) : Junction(ju), dips(), dipsOrig() { }
0085 
0086   ColourJunction(const ColourJunction& ju) : Junction(Junction(ju)), dips(),
0087     dipsOrig() { for(int i = 0;i < 3;++i) {
0088       dips[i] = ju.dips[i]; dipsOrig[i] = ju.dipsOrig[i];}
0089   }
0090   ColourJunction& operator=( const ColourJunction& ju) {
0091     this->Junction::operator=(ju);
0092     for(int i = 0;i < 3;++i) {
0093       dips[i] = ju.dips[i]; dipsOrig[i] = ju.dipsOrig[i];
0094     }
0095     return (*this);
0096   }
0097 
0098   ColourDipolePtr getColDip(int i) {return dips[i];}
0099   void setColDip(int i, ColourDipolePtr dip) {dips[i] = dip;}
0100   ColourDipolePtr dips[3];
0101   ColourDipolePtr dipsOrig[3];
0102   void list() const;
0103 
0104 };
0105 
0106 //==========================================================================
0107 
0108 // TrialReconnection class.
0109 
0110 //--------------------------------------------------------------------------
0111 
0112 class TrialReconnection {
0113 
0114 public:
0115 
0116   TrialReconnection(ColourDipolePtr dip1In = 0, ColourDipolePtr dip2In = 0,
0117     ColourDipolePtr dip3In = 0, ColourDipolePtr dip4In = 0, int modeIn = 0,
0118     double lambdaDiffIn = 0) {
0119     dips.push_back(dip1In); dips.push_back(dip2In);
0120     dips.push_back(dip3In); dips.push_back(dip4In);
0121     mode = modeIn; lambdaDiff = lambdaDiffIn;
0122   }
0123 
0124   void list() {
0125     cout << "mode: " << mode << " " << "lambdaDiff: " << lambdaDiff << endl;
0126     for (int i = 0;i < int(dips.size()) && dips[i] != 0;++i) {
0127       cout << "   "; dips[i]->list(); }
0128   }
0129 
0130   vector<ColourDipolePtr> dips;
0131   int mode;
0132   double lambdaDiff;
0133 
0134 };
0135 
0136 //==========================================================================
0137 
0138 // ColourParticle class.
0139 
0140 //--------------------------------------------------------------------------
0141 
0142 class ColourParticle : public Particle {
0143 
0144 public:
0145 
0146  ColourParticle(const Particle& ju) : Particle(ju), isJun(), junKind() {}
0147 
0148   vector<vector<ColourDipolePtr> > dips;
0149   vector<bool> colEndIncluded, acolEndIncluded;
0150   vector<ColourDipolePtr> activeDips;
0151   bool isJun;
0152   int junKind;
0153 
0154   // Printing functions, intended for debugging.
0155   void listParticle();
0156   void listActiveDips();
0157   void listDips();
0158 
0159 };
0160 
0161 //==========================================================================
0162 
0163 // The ColourReconnection class handles the colour reconnection.
0164 
0165 //--------------------------------------------------------------------------
0166 
0167 class ColourReconnection : public ColourReconnectionBase {
0168 
0169 public:
0170 
0171   // Constructor
0172   ColourReconnection() : allowJunctions(), sameNeighbourCol(),
0173     singleReconOnly(), lowerLambdaOnly(), allowDiqJunCR(), nSys(),
0174     nReconCols(), swap1(), swap2(), reconnectMode(), flipMode(),
0175     timeDilationMode(), eCM(), sCM(), pT0(), pT20Rec(), pT0Ref(), ecmRef(),
0176     ecmPow(), reconnectRange(), m0(), mPseudo(), m2Lambda(), fracGluon(),
0177     dLambdaCut(), timeDilationPar(), timeDilationParGeV(), tfrag(), blowR(),
0178     blowT(), rHadron(), kI(), dipMaxDist(), nColMove() {}
0179 
0180   // Initialization.
0181   bool init();
0182 
0183   // New beams possible for handling of hard diffraction.
0184   void reassignBeamPtrs( BeamParticle* beamAPtrIn,
0185     BeamParticle* beamBPtrIn) {
0186     beamAPtr = beamAPtrIn; beamBPtr = beamBPtrIn;}
0187 
0188   // Do colour reconnection for current event.
0189   bool next( Event & event, int oldSize);
0190 
0191 private:
0192 
0193   // Constants: could only be changed in the code itself.
0194   static const double MINIMUMGAIN, MINIMUMGAINJUN, TINYP1P2;
0195   static const int MAXRECONNECTIONS;
0196 
0197   // Variables needed.
0198   bool   allowJunctions, sameNeighbourCol, singleReconOnly, lowerLambdaOnly;
0199   bool   allowDiqJunCR;
0200   int    nSys, nReconCols, swap1, swap2, reconnectMode, flipMode,
0201          timeDilationMode;
0202   double eCM, sCM, pT0, pT20Rec, pT0Ref, ecmRef, ecmPow, reconnectRange,
0203          m0, mPseudo, m2Lambda, fracGluon, dLambdaCut, timeDilationPar,
0204          timeDilationParGeV, tfrag, blowR, blowT, rHadron, kI;
0205   double dipMaxDist;
0206 
0207   // List of current dipoles.
0208   vector<ColourDipolePtr> dipoles, usedDipoles;
0209 
0210   // Last used dipole index, used for sorting.
0211   int dipoleIndex{0};
0212 
0213   // Add a dipole and increment index.
0214   void addDipole(int colIn = 0, int iColIn = 0, int iAcolIn = 0,
0215     int colReconnectionIn = 0, bool isJunIn = false, bool isAntiJunIn = false,
0216     bool isActiveIn = true, bool isRealIn = false) {
0217     dipoles.push_back(make_shared<ColourDipole>(colIn, iColIn, iAcolIn,
0218         colReconnectionIn, isJunIn, isAntiJunIn, isActiveIn, isRealIn));
0219     dipoles.back()->index = ++dipoleIndex;
0220   }
0221 
0222   // Add a dipole and increment index.
0223   void addDipole(const ColourDipole& dipole) {
0224     dipoles.push_back(make_shared<ColourDipole>(dipole));
0225     dipoles.back()->index = ++dipoleIndex;
0226   }
0227 
0228   // Lists of particles, junctions and trials.
0229   vector<ColourJunction> junctions;
0230   vector<ColourParticle> particles;
0231   vector<TrialReconnection> junTrials, dipTrials;
0232   vector<vector<int> > iColJun;
0233   vector<double> formationTimes;
0234 
0235   // This is only to access the function call junctionRestFrame.
0236   StringFragmentation stringFragmentation;
0237 
0238   // This class is used to calculate the string length.
0239   StringLength stringLength;
0240 
0241   // Do colour reconnection for the event using the new model.
0242   bool nextNew( Event & event, int oldSize);
0243 
0244   // Simple test swap between two dipoles.
0245   void swapDipoles(ColourDipolePtr& dip1, ColourDipolePtr& dip2,
0246     bool back = false);
0247 
0248   // Setup the dipoles.
0249   void setupDipoles( Event& event, int iFirst = 0);
0250 
0251   // Form pseuparticle of a given dipole (or junction system).
0252   void makePseudoParticle(ColourDipolePtr& dip, int status,
0253     bool setupDone = false);
0254 
0255   // Find the indices in the particle list of the junction and also their
0256   // respectively leg numbers.
0257   bool getJunctionIndices(const ColourDipolePtr& dip, int &iJun, int &i0,
0258     int &i1, int &i2, int &junLeg0, int &junLeg1, int &junLeg2) const;
0259 
0260   // Form all possible pseudoparticles.
0261   void makeAllPseudoParticles(Event & event, int iFirst = 0);
0262 
0263   // Update all colours in the event.
0264   void updateEvent( Event& event, int iFirst = 0);
0265 
0266   double calculateStringLength( const ColourDipolePtr& dip,
0267     vector<ColourDipolePtr> & dips);
0268 
0269   // Calculate the string length for two event indices.
0270   double calculateStringLength( int i, int j) const;
0271 
0272   // Calculate the length of a single junction
0273   // given the 3 entries in the particle list.
0274   double calculateJunctionLength(const int i, const int j, const int k) const;
0275 
0276   // Calculate the length of a double junction,
0277   // given the 4 entries in the particle record.
0278   // First two are expected to be the quarks and second two the anti quarks.
0279   double calculateDoubleJunctionLength( const int i, const int j, const int k,
0280     const int l) const;
0281 
0282   // Find all the particles connected in the junction.
0283   // If a single junction, the size of iParticles should be 3.
0284   // For multiple junction structures, the size will increase.
0285   bool findJunctionParticles( int iJun, vector<int>& iParticles,
0286     vector<bool> &usedJuns, int &nJuns, vector<ColourDipolePtr> &dips);
0287 
0288   // Do a single trial reconnection.
0289   void singleReconnection( ColourDipolePtr& dip1, ColourDipolePtr& dip2);
0290 
0291   // Do a single trial reconnection to form a junction.
0292   void singleJunction(ColourDipolePtr& dip1, ColourDipolePtr& dip2);
0293 
0294   // Do a single trial reconnection to form a junction.
0295   void singleJunction(const ColourDipolePtr& dip1, const ColourDipolePtr& dip2,
0296     const ColourDipolePtr& dip3);
0297 
0298   // Print the chain containing the dipole.
0299   void listChain(ColourDipolePtr& dip);
0300 
0301   // Print all the chains.
0302   void listAllChains();
0303 
0304   // Print dipoles, intended for debuggning purposes.
0305   void listDipoles( bool onlyActive = false, bool onlyReal = false) const;
0306 
0307   // Print particles, intended for debugging purposes.
0308   void listParticles() const;
0309 
0310   // Print junctions, intended for debugging purposes.
0311   void listJunctions() const;
0312 
0313   // Check that the current dipole setup is consistent. Debug purpose only.
0314   void checkDipoles();
0315 
0316   // Check that the current dipole setup is consistent. Debug purpose only.
0317   void checkRealDipoles(Event& event, int iFirst);
0318 
0319   // Calculate the invariant mass of a dipole.
0320   double mDip(const ColourDipolePtr& dip) const;
0321 
0322   // Find a vertex of the (anti)-colour side of the dipole. If
0323   // connected to a junction, recurse using the other junction
0324   // dipoles.
0325   Vec4 getVProd(const ColourDipolePtr& dip, bool anti) const;
0326 
0327   // Find an average vertex of the (anti)-colour sides of the dipoles
0328   // connected to the given junction (not incuding the given dipole).
0329   Vec4 getVProd(int iJun, const ColourDipolePtr& dip, bool anti) const;
0330 
0331   // Check that the distance between the impact parameter centers of
0332   // the dipoles are within the allowed range of dipMaxDist.
0333   bool checkDist(const ColourDipolePtr& dip1, const ColourDipolePtr& dip2)
0334     const;
0335 
0336   // Find the neighbour to anti colour side. Return false if the dipole is
0337   // connected to a junction or the new particle has a junction inside of it.
0338   bool findAntiNeighbour(ColourDipolePtr& dip);
0339 
0340   // Find the neighbour to colour side. Return false if the dipole is
0341   // connected to a junction or the new particle has a junction inside of it.
0342   bool findColNeighbour(ColourDipolePtr& dip);
0343 
0344   // Check that trials do not contain junctions / unusable pseudoparticles.
0345   bool checkJunctionTrials();
0346 
0347   // Store all dipoles connected to the ones used in the junction connection.
0348   void storeUsedDips(TrialReconnection& trial);
0349 
0350   // Change colour structure to describe the reconnection in juncTrial.
0351   bool doJunctionTrial(Event& event, TrialReconnection& juncTrial);
0352 
0353   // Change colour structure to describe the reconnection in juncTrial.
0354   void doDipoleTrial(TrialReconnection& trial);
0355 
0356   // Change colour structure if it is three dipoles forming a junction system.
0357   bool doTripleJunctionTrial(Event& event, TrialReconnection& juncTrial);
0358 
0359   // Calculate the difference between the old and new lambda.
0360   double getLambdaDiff(const ColourDipolePtr& dip1,
0361     const ColourDipolePtr& dip2, const ColourDipolePtr& dip3,
0362     const ColourDipolePtr& dip4, const int mode) const;
0363 
0364   // Calculate the difference between the old and new lambda (dipole swap).
0365   double getLambdaDiff(ColourDipolePtr& dip1, ColourDipolePtr& dip2);
0366 
0367   // Update the list of dipole trial swaps to account for latest swap.
0368   void updateDipoleTrials();
0369 
0370   // Update the list of dipole trial swaps to account for latest swap.
0371   void updateJunctionTrials();
0372 
0373   // Check whether up to four dipoles are 'causally' connected.
0374   bool checkTimeDilation(const ColourDipolePtr& dip1 = 0,
0375     const ColourDipolePtr& dip2 = 0, const ColourDipolePtr& dip3 = 0,
0376     const ColourDipolePtr& dip4 = 0) const;
0377 
0378   // Check whether two four momenta are casually connected.
0379   bool checkTimeDilation(const Vec4& p1, const Vec4& p2, const double t1,
0380     const double t2) const;
0381 
0382   // Find the momentum of the dipole.
0383   Vec4 getDipoleMomentum(const ColourDipolePtr& dip) const;
0384 
0385   // Find all particles connected to a junction system (particle list).
0386   void addJunctionIndices(const int iSinglePar, set<int> &iPar,
0387     set<int> &usedJuncs) const;
0388 
0389   // Find all the formation times.
0390   void setupFormationTimes( Event & event);
0391 
0392   // Get the mass of all partons connected to a junction system (event list).
0393   double getJunctionMass(Event & event, int col);
0394 
0395   // Find all particles connected to a junction system (event list).
0396   void addJunctionIndices(const Event & event, const int iSinglePar,
0397     set<int> &iPar, set<int> &usedJuncs) const;
0398 
0399   // The old MPI-based scheme.
0400   bool reconnectMPIs( Event& event, int oldSize);
0401 
0402   // Vectors and methods needed for the new gluon-move model.
0403 
0404   // Array of (indices of) all final coloured particles.
0405   vector<int> iReduceCol, iExpandCol;
0406 
0407   // Array of all lambda distances between coloured partons.
0408   int nColMove;
0409   vector<double> lambdaijMove;
0410 
0411   // Function to return lambda value from array.
0412   double lambda12Move( int i, int j) {
0413     int iAC = iReduceCol[i]; int jAC = iReduceCol[j];
0414     return lambdaijMove[nColMove * min( iAC, jAC) + max( iAC, jAC)];
0415   }
0416 
0417   // Function to return lambda(i,j) + lambda(i,k) - lambda(j,k).
0418   double lambda123Move( int i, int j, int k) {
0419     int iAC = iReduceCol[i]; int jAC = iReduceCol[j]; int kAC = iReduceCol[k];
0420     return lambdaijMove[nColMove * min( iAC, jAC) + max( iAC, jAC)]
0421          + lambdaijMove[nColMove * min( iAC, kAC) + max( iAC, kAC)]
0422          - lambdaijMove[nColMove * min( jAC, kAC) + max( jAC, kAC)];
0423   }
0424 
0425   // The new gluon-move scheme.
0426   bool reconnectMove( Event& event, int oldSize);
0427 
0428   // The common part for both Type I and II reconnections in e+e..
0429   bool reconnectTypeCommon( Event& event, int oldSize);
0430 
0431   // The e+e- type I CR model.
0432   map<double,pair<int,int> > reconnectTypeI( Event& event,
0433     vector<vector<ColourDipole> > &dips, Vec4 decays[2]);
0434   //  bool reconnectTypeI( Event& event, int oldSize);
0435 
0436   // The e+e- type II CR model.
0437   map<double,pair<int,int> > reconnectTypeII( Event& event,
0438     vector<vector<ColourDipole> > &dips, Vec4 decays[2]);
0439   //    bool reconnectTypeII( Event& event, int oldSize);
0440 
0441   // calculate the determinant of 3 * 3 matrix.
0442   double determinant3(vector<vector< double> >& vec);
0443 };
0444 
0445 //==========================================================================
0446 
0447 } // end namespace Pythia8
0448 
0449 #endif // Pythia8_ColourReconnection_H