Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:18

0001 // Analysis.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2024 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 Sphericity, Thrust, ClusterJet and CellJet classes.
0007 // Sphericity: sphericity analysis of the event.
0008 // Thrust: thrust analysis of the event.
0009 // ClusterJet: clustering jet finder.
0010 // CellJet: calorimetric cone jet finder.
0011 // SlowJet: recombination algorithm; lightweight version of FastJet.
0012 
0013 #ifndef Pythia8_Analysis_H
0014 #define Pythia8_Analysis_H
0015 
0016 #include "Pythia8/Basics.h"
0017 #include "Pythia8/Event.h"
0018 #include "Pythia8/PythiaStdlib.h"
0019 
0020 namespace Pythia8 {
0021 
0022 //==========================================================================
0023 
0024 // Sphericity class.
0025 // This class performs (optionally modified) sphericity analysis on an event.
0026 
0027 class Sphericity {
0028 
0029 public:
0030 
0031   // Constructor.
0032   Sphericity(double powerIn = 2., int selectIn = 2) : power(powerIn),
0033     select(selectIn), eVal1(), eVal2(), eVal3(), nFew(0) {powerInt = 0;
0034     if (abs(power - 1.) < 0.01) powerInt = 1;
0035     if (abs(power - 2.) < 0.01) powerInt = 2;
0036     powerMod = 0.5 * power - 1.;}
0037 
0038   // Analyze event.
0039   bool analyze(const Event& event);
0040 
0041   // Return info on results of analysis.
0042   double sphericity()      const {return 1.5 * (eVal2 + eVal3);}
0043   double aplanarity()      const {return 1.5 * eVal3;}
0044   double eigenValue(int i) const {return (i < 2) ? eVal1 :
0045     ( (i < 3) ? eVal2 : eVal3 ) ;}
0046   Vec4 eventAxis(int i)    const {return (i < 2) ? eVec1 :
0047     ( (i < 3) ? eVec2 : eVec3 ) ;}
0048 
0049   // Provide a listing of the info.
0050   void list() const;
0051 
0052   // Tell how many events could not be analyzed.
0053   int nError() const {return nFew;}
0054 
0055 private:
0056 
0057   // Constants: could only be changed in the code itself.
0058   static const int    NSTUDYMIN, TIMESTOPRINT;
0059   static const double P2MIN, EIGENVALUEMIN;
0060 
0061   // Properties of analysis.
0062   double power;
0063   int    select, powerInt;
0064   double powerMod;
0065 
0066   // Outcome of analysis.
0067   double eVal1, eVal2, eVal3;
0068   Vec4   eVec1, eVec2, eVec3;
0069 
0070   // Error statistics;
0071   int    nFew;
0072 
0073 };
0074 
0075 //==========================================================================
0076 
0077 // Thrust class.
0078 // This class performs thrust analysis on an event.
0079 
0080 class Thrust {
0081 
0082 public:
0083 
0084   // Constructor.
0085   Thrust(int selectIn = 2) : select(selectIn), eVal1(), eVal2(), eVal3(),
0086     nFew(0) {}
0087 
0088   // Analyze event.
0089   bool analyze(const Event& event);
0090 
0091   // Return info on results of analysis.
0092   double thrust()       const {return eVal1;}
0093   double tMajor()       const {return eVal2;}
0094   double tMinor()       const {return eVal3;}
0095   double oblateness()   const {return eVal2 - eVal3;}
0096   Vec4 eventAxis(int i) const {return (i < 2) ? eVec1 :
0097     ( (i < 3) ? eVec2 : eVec3 ) ;}
0098 
0099   // Provide a listing of the info.
0100   void list() const;
0101 
0102   // Tell how many events could not be analyzed.
0103   int nError() const {return nFew;}
0104 
0105 private:
0106 
0107   // Constants: could only be changed in the code itself.
0108   static const int    NSTUDYMIN, TIMESTOPRINT;
0109   static const double CROSSMIN, MAJORMIN;
0110 
0111   // Properties of analysis.
0112   int    select;
0113 
0114   // Outcome of analysis.
0115   double eVal1, eVal2, eVal3;
0116   Vec4   eVec1, eVec2, eVec3;
0117 
0118   // Error statistics;
0119   int    nFew;
0120 
0121 };
0122 
0123 //==========================================================================
0124 
0125 // SingleClusterJet class.
0126 // Simple helper class to ClusterJet for a jet and its contents.
0127 
0128 class SingleClusterJet {
0129 
0130 public:
0131 
0132   // Constructors.
0133   SingleClusterJet(Vec4 pJetIn = 0., int motherIn = 0) :
0134     pJet(pJetIn), mother(motherIn), daughter(0), multiplicity(1),
0135     isAssigned(false) {pAbs = max( PABSMIN, pJet.pAbs());}
0136   SingleClusterJet(const SingleClusterJet& j) {
0137     pJet = j.pJet;  mother = j.mother; daughter = j.daughter;
0138     multiplicity = j.multiplicity; pAbs = j.pAbs;
0139     isAssigned = j.isAssigned; }
0140   SingleClusterJet& operator=(const SingleClusterJet& j) { if (this != &j)
0141     { pJet = j.pJet;  mother = j.mother; daughter = j.daughter;
0142     multiplicity = j.multiplicity; pAbs = j.pAbs;
0143     isAssigned = j.isAssigned;} return *this; }
0144 
0145   // Properties of jet.
0146   // Note: mother, daughter and isAssigned only used for original
0147   // particles, multiplicity and pTemp only for reconstructed jets.
0148   Vec4   pJet;
0149   int    mother, daughter, multiplicity;
0150   bool   isAssigned;
0151   double pAbs;
0152   Vec4   pTemp;
0153 
0154   // Distance measures (Lund, JADE, Durham) with friend.
0155   friend double dist2Fun(int measure, const SingleClusterJet& j1,
0156     const SingleClusterJet& j2);
0157 
0158 private:
0159 
0160   // Constants: could only be changed in the code itself.
0161   static const double PABSMIN;
0162 
0163 } ;
0164 
0165 //--------------------------------------------------------------------------
0166 
0167 // Namespace function declarations; friend of SingleClusterJet.
0168 
0169 // Distance measures (Lund, JADE, Durham) with friend.
0170 double dist2Fun(int measure, const SingleClusterJet& j1,
0171   const SingleClusterJet& j2);
0172 
0173 //==========================================================================
0174 
0175 // ClusterJet class.
0176 // This class performs a jet clustering according to different
0177 // distance measures: Lund, JADE or Durham.
0178 
0179 class ClusterJet {
0180 
0181 public:
0182 
0183   // Constructor.
0184   ClusterJet(string measureIn = "Lund", int selectIn = 2, int massSetIn = 2,
0185     bool preclusterIn = false, bool reassignIn = false) : measure(1),
0186     select(selectIn), massSet(massSetIn), doPrecluster(preclusterIn),
0187     doReassign(reassignIn), yScale(), pTscale(), nJetMin(), nJetMax(),
0188     dist2Join(), dist2BigMin(), distPre(), dist2Pre(), nParticles(), nFew(0)
0189     {
0190       char firstChar = toupper(measureIn[0]);
0191       if (firstChar == 'J') measure = 2;
0192       if (firstChar == 'D') measure = 3;
0193     }
0194 
0195   // Analyze event.
0196   bool analyze(const Event& event, double yScaleIn, double pTscaleIn,
0197     int nJetMinIn = 1, int nJetMaxIn = 0);
0198 
0199   // Return info on jets produced.
0200   int  size()      const {return jets.size();}
0201   Vec4 p(int i)    const {return jets[i].pJet;}
0202   int  mult(int i) const {return jets[i].multiplicity;}
0203 
0204   // Return belonging of particle to one of the jets (-1 if none).
0205   int jetAssignment(int i) const {
0206     for (int iP = 0; iP < int(particles.size()); ++iP)
0207     if (particles[iP].mother == i) return particles[iP].daughter;
0208     return -1;}
0209 
0210   // Provide a listing of the info.
0211   void list() const;
0212 
0213   // Return info on clustering values.
0214   int    distanceSize() const {return distances.size();}
0215   double distance(int i) const {
0216     return (i < distanceSize()) ? distances[i] : 0.; }
0217 
0218   // Tell how many events could not be analyzed.
0219   int nError() const {return nFew;}
0220 
0221 private:
0222 
0223   // Constants: could only be changed in the code itself.
0224   static const int    TIMESTOPRINT;
0225   static const double PIMASS, PABSMIN, PRECLUSTERFRAC, PRECLUSTERSTEP;
0226 
0227   // Properties of analysis.
0228   int    measure, select, massSet;
0229   bool   doPrecluster, doReassign;
0230   double yScale, pTscale;
0231   int    nJetMin, nJetMax;
0232 
0233   // Temporary results.
0234   double dist2Join, dist2BigMin, distPre, dist2Pre;
0235   vector<SingleClusterJet> particles;
0236   int    nParticles;
0237 
0238   // Error statistics;
0239   int    nFew;
0240 
0241   // Member functions for some operations (for clarity).
0242   void precluster();
0243   void reassign();
0244 
0245   // Outcome of analysis: ET-ordered list of jets.
0246   vector<SingleClusterJet> jets;
0247 
0248   // Outcome of analysis: the distance values where the jets were merged.
0249   deque<double> distances;
0250 
0251 };
0252 
0253 //==========================================================================
0254 
0255 // SingleCell class.
0256 // Simple helper class to CellJet for a cell and its contents.
0257 
0258 class SingleCell {
0259 
0260 public:
0261 
0262   // Constructor.
0263   SingleCell(int iCellIn = 0, double etaCellIn = 0., double phiCellIn = 0.,
0264     double eTcellIn = 0., int multiplicityIn = 0) : iCell(iCellIn),
0265     etaCell(etaCellIn), phiCell(phiCellIn), eTcell(eTcellIn),
0266     multiplicity(multiplicityIn), canBeSeed(true), isUsed(false),
0267     isAssigned(false) {}
0268 
0269   // Properties of cell.
0270   int    iCell;
0271   double etaCell, phiCell, eTcell;
0272   int    multiplicity;
0273   bool   canBeSeed, isUsed, isAssigned;
0274 
0275 } ;
0276 
0277 //==========================================================================
0278 
0279 // SingleCellJet class.
0280 // Simple helper class to CellJet for a jet and its contents.
0281 
0282 class SingleCellJet {
0283 
0284 public:
0285 
0286   // Constructor.
0287   SingleCellJet(double eTjetIn = 0., double etaCenterIn = 0.,
0288     double phiCenterIn = 0., double etaWeightedIn = 0.,
0289     double phiWeightedIn = 0., int multiplicityIn = 0,
0290     Vec4 pMassiveIn = 0.) : eTjet(eTjetIn), etaCenter(etaCenterIn),
0291     phiCenter(phiCenterIn), etaWeighted(etaWeightedIn),
0292     phiWeighted(phiWeightedIn), multiplicity(multiplicityIn),
0293     pMassive(pMassiveIn) {}
0294 
0295   // Properties of jet.
0296   double eTjet, etaCenter, phiCenter, etaWeighted, phiWeighted;
0297   int    multiplicity;
0298   Vec4   pMassive;
0299 
0300 } ;
0301 
0302 //==========================================================================
0303 
0304 // CellJet class.
0305 // This class performs a cone jet search in (eta, phi, E_T) space.
0306 
0307 class CellJet {
0308 
0309 public:
0310 
0311   // Constructor.
0312   CellJet(double etaMaxIn = 5., int nEtaIn = 50, int nPhiIn = 32,
0313     int selectIn = 2, int smearIn = 0, double resolutionIn = 0.5,
0314     double upperCutIn = 2., double thresholdIn = 0., Rndm* rndmPtrIn = 0)
0315     : etaMax(etaMaxIn), nEta(nEtaIn), nPhi(nPhiIn), select(selectIn),
0316     smear(smearIn), resolution(resolutionIn), upperCut(upperCutIn),
0317     threshold(thresholdIn), eTjetMin(), coneRadius(), eTseed(), nFew(0),
0318     rndmPtr(rndmPtrIn) { }
0319 
0320   // Analyze event.
0321   bool analyze(const Event& event, double eTjetMinIn = 20.,
0322     double coneRadiusIn = 0.7, double eTseedIn = 1.5);
0323 
0324   // Return info on results of analysis.
0325   int    size()              const {return jets.size();}
0326   double eT(int i)           const {return jets[i].eTjet;}
0327   double etaCenter(int i)    const {return jets[i].etaCenter;}
0328   double phiCenter(int i)    const {return jets[i].phiCenter;}
0329   double etaWeighted(int i)  const {return jets[i].etaWeighted;}
0330   double phiWeighted(int i)  const {return jets[i].phiWeighted;}
0331   int    multiplicity(int i) const {return jets[i].multiplicity;}
0332   Vec4   pMassless(int i)    const {return jets[i].eTjet * Vec4(
0333            cos(jets[i].phiWeighted),  sin(jets[i].phiWeighted),
0334           sinh(jets[i].etaWeighted), cosh(jets[i].etaWeighted) );}
0335   Vec4   pMassive(int i)     const {return jets[i].pMassive;}
0336   double m(int i)            const {return jets[i].pMassive.mCalc();}
0337 
0338   // Provide a listing of the info.
0339   void list() const;
0340 
0341   // Tell how many events could not be analyzed: so far never.
0342   int nError() const {return nFew;}
0343 
0344 private:
0345 
0346   // Constants: could only be changed in the code itself.
0347   static const int    TIMESTOPRINT;
0348 
0349   // Properties of analysis.
0350   double etaMax;
0351   int    nEta, nPhi, select, smear;
0352   double resolution, upperCut, threshold;
0353   double eTjetMin, coneRadius, eTseed;
0354 
0355   // Error statistics;
0356   int    nFew;
0357 
0358   // Outcome of analysis: ET-ordered list of jets.
0359   vector<SingleCellJet> jets;
0360 
0361   // Pointer to the random number generator (needed for energy smearing).
0362   Rndm* rndmPtr;
0363 
0364 };
0365 
0366 //==========================================================================
0367 
0368 // SlowJetHook class.
0369 // Base class, used to derive your own class with your selection criteria.
0370 
0371 class SlowJetHook {
0372 
0373 public:
0374 
0375   // Destructor.
0376   virtual ~SlowJetHook() { }
0377 
0378   // Method to be overloaded.
0379   // It will be called for all final-state particles, one at a time, and
0380   // should return true if the particle should be analyzed, false if not.
0381   // The particle is in location iSel of the event record.
0382   // If you wish you can also modify the four-momentum and mass that will
0383   //  be used in the analysis, without affecting the event record itself,
0384   // by changing pSel and mSel. Remember to respect E^2 - p^2 = m^2.
0385   virtual bool include(int iSel, const Event& event, Vec4& pSel,
0386     double& mSel) = 0;
0387 
0388 };
0389 
0390 //==========================================================================
0391 
0392 // SingleSlowJet class.
0393 // Simple helper class to SlowJet for a jet and its contents.
0394 
0395 class SingleSlowJet {
0396 
0397 public:
0398 
0399   // Constructors.
0400   SingleSlowJet( Vec4 pIn = 0., double pT2In = 0., double yIn = 0.,
0401       double phiIn = 0., int idxIn = 0) : p(pIn), pT2(pT2In), y(yIn),
0402       phi(phiIn), mult(1) { idx.insert(idxIn); }
0403   SingleSlowJet(const SingleSlowJet& ssj) : p(ssj.p), pT2(ssj.pT2),
0404     y(ssj.y), phi(ssj.phi), mult(ssj.mult), idx(ssj.idx) { }
0405   SingleSlowJet& operator=(const SingleSlowJet& ssj) { if (this != &ssj)
0406     { p = ssj.p; pT2 = ssj.pT2; y = ssj.y; phi = ssj.phi;
0407     mult = ssj.mult; idx = ssj.idx; } return *this; }
0408 
0409   // Properties of jet.
0410   Vec4     p;
0411   double   pT2, y, phi;
0412   int      mult;
0413   set<int> idx;
0414 
0415 };
0416 
0417 //==========================================================================
0418 
0419 // SlowJet class.
0420 // This class performs a recombination jet search in (y, phi, pT) space.
0421 
0422 class SlowJet {
0423 
0424 public:
0425 
0426   // Constructor.
0427   SlowJet(int powerIn, double Rin, double pTjetMinIn = 0.,
0428     double etaMaxIn = 25., int selectIn = 2, int massSetIn = 2,
0429     SlowJetHook* sjHookPtrIn = 0, bool useFJcoreIn = true,
0430     bool useStandardRin = true) : power(powerIn), R(Rin),
0431     pTjetMin(pTjetMinIn), etaMax(etaMaxIn), select(selectIn),
0432     massSet(massSetIn), sjHookPtr(sjHookPtrIn), useFJcore(useFJcoreIn),
0433     useStandardR(useStandardRin), origSize(), clSize(), clLast(), jtSize(),
0434     iMin(), jMin(), dPhi(), dijTemp(), dMin() { isAnti = (power < 0);
0435     isKT = (power > 0); R2 = R*R; pT2jetMin = pTjetMin*pTjetMin;
0436     cutInEta = (etaMax <= 20.); chargedOnly = (select > 2);
0437     visibleOnly = (select == 2); modifyMass = (massSet < 2);
0438     noHook = (sjHookPtr == 0);}
0439 
0440   // Destructor.
0441   virtual ~SlowJet() {};
0442 
0443   // Analyze event, all in one go.
0444   bool analyze(const Event& event) {
0445     if ( !setup(event) ) return false;
0446     if (useFJcore) return clusterFJ();
0447     while (clSize > 0) doStep();
0448     return true; }
0449 
0450   // Set up list of particles to analyze, and initial distances.
0451   bool setup(const Event& event);
0452 
0453   // Do one recombination step, possibly giving a jet.
0454   virtual bool doStep();
0455 
0456   // Do several recombinations steps, if possible.
0457   bool doNSteps(int nStep) { if (useFJcore) return false;
0458     while(nStep > 0 && clSize > 0) { doStep(); --nStep;}
0459     return (nStep == 0); }
0460 
0461   // Do recombinations until fixed numbers of clusters and jets remain.
0462   bool stopAtN(int nStop) { if (useFJcore) return false;
0463     while (clSize + jtSize > nStop && clSize > 0) doStep();
0464     return (clSize + jtSize == nStop); }
0465 
0466   // Return info on jet (+cluster) results of analysis.
0467   int    sizeOrig()          const {return origSize;}
0468   int    sizeJet()           const {return jtSize;}
0469   int    sizeAll()           const {return jtSize + clSize;}
0470   double pT(int i)           const {return (i < jtSize)
0471     ? sqrt(jets[i].pT2) : sqrt(clusters[i - jtSize].pT2);}
0472   double y(int i)            const {return (i < jtSize)
0473     ? jets[i].y : clusters[i - jtSize].y;}
0474   double phi(int i)          const {return (i < jtSize)
0475     ? jets[i].phi : clusters[i - jtSize].phi;}
0476   Vec4   p(int i)            const {return (i < jtSize)
0477     ? jets[i].p : clusters[i - jtSize].p;}
0478   double m(int i)            const {return (i < jtSize)
0479     ? jets[i].p.mCalc() : clusters[i - jtSize].p.mCalc();}
0480   int    multiplicity(int i) const {return (i < jtSize)
0481     ? jets[i].mult : clusters[i - jtSize].mult;}
0482 
0483   // Return info on next step to be taken.
0484   int    iNext() const {return (iMin == -1) ? -1 : iMin + jtSize;}
0485   int    jNext() const {return (jMin == -1) ? -1 : jMin + jtSize;}
0486   double dNext() const {return dMin;}
0487 
0488   // Provide a listing of the info.
0489   void list(bool listAll = false) const;
0490 
0491   // Give a list of all particles in the jet.
0492   vector<int> constituents(int j) { vector<int> cTemp;
0493     for (set<int>::iterator idxTmp = jets[j].idx.begin();
0494       idxTmp != jets[j].idx.end(); ++idxTmp) cTemp.push_back( *idxTmp);
0495     return cTemp;
0496   }
0497 
0498   // Give a list of all particles in the cluster.
0499   vector<int> clusConstituents(int j) { vector<int> cTemp;
0500     for (set<int>::iterator idxTmp = clusters[j].idx.begin();
0501       idxTmp != clusters[j].idx.end(); ++idxTmp) cTemp.push_back( *idxTmp);
0502     return cTemp;
0503   }
0504 
0505   // Give the index of the jet that the particle i of the event record
0506   // belongs to. Returns -1 if particle i is not found in a jet.
0507   int jetAssignment(int i) {
0508     for (int j = 0; j < sizeJet(); ++j)
0509       if (jets[j].idx.find(i) != jets[j].idx.end()) return j;
0510     return -1;
0511   }
0512 
0513   // Remove a jet.
0514   void removeJet(int i) {
0515     if (i < 0 || i >= jtSize) return;
0516     jets.erase(jets.begin() + i);
0517     jtSize--;
0518   }
0519 
0520 protected:
0521 
0522   // Constants: could only be changed in the code itself.
0523   static const int    TIMESTOPRINT;
0524   static const double PIMASS, TINY;
0525 
0526   // Properties of analysis as such.
0527   int    power;
0528   double R, pTjetMin, etaMax, R2, pT2jetMin;
0529   int    select, massSet;
0530   // SlowJetHook can be used to tailor particle selection step.
0531   SlowJetHook* sjHookPtr;
0532   bool   useFJcore, useStandardR, isAnti, isKT, cutInEta, chargedOnly,
0533          visibleOnly, modifyMass, noHook;
0534 
0535   // Intermediate clustering objects and final jet objects.
0536   vector<SingleSlowJet> clusters;
0537   vector<SingleSlowJet> jets;
0538 
0539   // Intermediate clustering distances.
0540   vector<double> diB;
0541   vector<double> dij;
0542 
0543   // Other intermediate variables.
0544   int    origSize, clSize, clLast, jtSize, iMin, jMin;
0545   double dPhi, dijTemp, dMin;
0546 
0547   // Find next cluster pair to join.
0548   virtual void findNext();
0549 
0550   // Use FJcore interface to perform clustering.
0551   bool clusterFJ();
0552 
0553 };
0554 
0555 //==========================================================================
0556 
0557 } // end namespace Pythia8
0558 
0559 #endif // end Pythia8_Analysis_H