Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:19:19

0001 /*******************************************************************************
0002  * Copyright (c) The JETSCAPE Collaboration, 2018
0003  *
0004  * Modular, task-based framework for simulating all aspects of heavy-ion collisions
0005  * 
0006  * For the list of contributors see AUTHORS.
0007  *
0008  * Report issues at https://github.com/JETSCAPE/JETSCAPE/issues
0009  *
0010  * or via email to bugs.jetscape@gmail.com
0011  *
0012  * Distributed under the GNU General Public License 3.0 (GPLv3 or later).
0013  * See COPYING for details.
0014  ******************************************************************************/
0015 
0016 /** Provides JetScapeParticleBase and derived classes Parton, Hadron
0017 
0018     \class Jetscape::JetScapeParticleBase
0019     * A JetScapeParticleBase derives PRIVARTELY from FastJet PseudoJet and has additional information:
0020     *  - PID (from PDG) and rest mass (these should eventually be coupled and only PID kept track of internally)
0021     *  - A location (creation point) 4-vector
0022     *  - a label and a status 
0023     *  - currently additional information that should be moved to derived classes or only used as UserInfo
0024     * 
0025     * The design choice of protected inheritance is due to a disconnect between available packages.
0026     * The overwhelming majority of the theory community expects the 0 component to be time/energy, 
0027     * whereas FastJet (and others, like ROOT) prefer t,e to be the fourth component.
0028     * Private inheritance means we can inherit and make accessible safe methods (with C++11 using),
0029     * while protecting users from unsafe (explicit component access) ones.
0030     * Note that this is only necessary because otherwise it's impossible to disallow 
0031     * constructors and getters that explicitly assume indices!
0032     * IF we could get rid of those or change to the fastjet convention,
0033     * we could derive publicly and get a true Is_A relationship. Alas.
0034     * 
0035     * You can in principle use the base class directly, but it's recommended to use the derived classes
0036     * Parton and/or (todo) Hadron, Lepton, ...
0037     * 
0038     * \warning
0039     * PseudoJet doesn't have a concept of rest mass, any mass related functions literally assume 
0040     * \f$M^2 = E^2 - p*p.\f$
0041     * Especially in the case of off-shell partons, the correct interpretation is 
0042     * \f$"M^2" = E^2 - p^2 == M0^2 + Q^2 == M0^2 + t\f$
0043     * Therefore, there is the dangerous possibility that functions like mass(), reset_PtYPhiM(...) can
0044     * be used by unwitting users and display unexpected behavior. 
0045     * For protection against this possibility, "mass"-related functions in PseudoJet are
0046     * not made available
0047     * 
0048     * Future considerations: 
0049     *   - We should consider
0050     *     making a Pythia8 installation mandatory; with pythia guaranteed to be present,
0051     *     the rest mass lookup could be automatically done using PDG data.
0052     *   - If ROOT were a mandatory part, TLorentzVector would be a good replacement for the homebrewed FourVector
0053     *   - If HepMc were a mandatory part, HepMc::FourVector would be a good replacement for the homebrewed FourVector
0054     */
0055 
0056 #ifndef JETSCAPEPARTICLES_H
0057 #define JETSCAPEPARTICLES_H
0058 
0059 #include <stdio.h>
0060 #include <math.h>
0061 #include "GTL/graph.h"
0062 #include "JetScapeConstants.h"
0063 #include "FourVector.h"
0064 #include "fjcore.hh"
0065 #include "JetScapeLogger.h"
0066 #include "PartonShower.h"
0067 
0068 #include "Pythia8/Pythia.h"
0069 
0070 #include <vector>
0071 #include <memory>
0072 #include <iostream>
0073 #include <sstream>
0074 #include <iomanip>
0075 
0076 using std::ostream;
0077 using std::weak_ptr;
0078 
0079 namespace Jetscape {
0080 
0081 class PartonShower;
0082 
0083 /**************************************************************************************************/
0084 //  BASE CLASS
0085 /*************************************************************************************************/
0086 
0087 class JetScapeParticleBase : protected fjcore::PseudoJet {
0088   friend class fjcore::PseudoJet;
0089 
0090   // unsafe
0091   // using fjcore::PseudoJet::PseudoJet;
0092   // using fjcore::PseudoJet::operator() (int i) const ;
0093   // inline double operator [] (int i) const { return (*this)(i); }; // this too
0094 
0095 public:
0096   // Disallow reset, it assumes different logic
0097   // using fjcore::PseudoJet::reset(double px, double py, double pz, double E);
0098   // using fjcore::PseudoJet::reset(const PseudoJet & psjet) {
0099   //   inline void reset_momentum(double px, double py, double pz, double E);
0100   //   inline void reset_momentum(const PseudoJet & pj);
0101 
0102   inline void reset_momentum(const double px, const double py, const double pz,
0103                              const double e) {
0104     fjcore::PseudoJet::reset_momentum(px, py, pz, e);
0105   }
0106 
0107   inline void reset_momentum(const FourVector &p) {
0108     fjcore::PseudoJet::reset_momentum(p.x(), p.y(), p.z(), p.t());
0109   }
0110 
0111   // Disallow the valarray return.
0112   // Can replace/and or provide a double[4] version with the right assumptions
0113   // std::valarray<double> four_mom() const;
0114   // enum { X=0, Y=1, Z=2, T=3, NUM_COORDINATES=4, SIZE=NUM_COORDINATES };
0115 
0116   // This _should_ work, but not taking chances for now
0117   // PseudoJet & boost(const PseudoJet & prest);
0118   // PseudoJet & unboost(const PseudoJet & prest);
0119 
0120   // Replace with appropriate functions. m is a tricky one.
0121   // inline double  m2() const {return (_E+_pz)*(_E-_pz)-_kt2;}
0122   // inline double  m() const;
0123   // inline double mperp2() const {return (_E+_pz)*(_E-_pz);}
0124   // inline double mperp() const {return sqrt(std::abs(mperp2()));}
0125   // inline double mt2() const {return (_E+_pz)*(_E-_pz);}
0126   // inline double mt() const {return sqrt(std::abs(mperp2()));}
0127 
0128   // Disallow functions containing M
0129   // inline void reset_PtYPhiM(...);
0130   // void reset_momentum_PtYPhiM(double pt, double y, double phi, double m=0.0);
0131 
0132   // // void set_cached_rap_phi(double rap, double phi);
0133 
0134   /// No implicit cast to PseudoJet is allowed, provide a conversion
0135   fjcore::PseudoJet GetPseudoJet() const { return PseudoJet(*this); }
0136 
0137   // import safe functions
0138   using fjcore::PseudoJet::px;
0139   using fjcore::PseudoJet::py;
0140   using fjcore::PseudoJet::pz;
0141   using fjcore::PseudoJet::e;
0142   using fjcore::PseudoJet::E;
0143 
0144   using fjcore::PseudoJet::phi;
0145   using fjcore::PseudoJet::phi_std;
0146   using fjcore::PseudoJet::phi_02pi;
0147   using fjcore::PseudoJet::rap;
0148   using fjcore::PseudoJet::rapidity;
0149   using fjcore::PseudoJet::pseudorapidity;
0150   using fjcore::PseudoJet::eta;
0151   using fjcore::PseudoJet::pt2;
0152   using fjcore::PseudoJet::pt;
0153   using fjcore::PseudoJet::perp2;
0154   using fjcore::PseudoJet::perp;
0155   using fjcore::PseudoJet::kt2;
0156 
0157   using fjcore::PseudoJet::modp2;
0158   using fjcore::PseudoJet::modp;
0159   using fjcore::PseudoJet::Et;
0160   using fjcore::PseudoJet::Et2;
0161 
0162   using fjcore::PseudoJet::kt_distance;
0163   using fjcore::PseudoJet::plain_distance;
0164   using fjcore::PseudoJet::squared_distance;
0165   using fjcore::PseudoJet::delta_R;
0166   using fjcore::PseudoJet::delta_phi_to;
0167   using fjcore::PseudoJet::beam_distance;
0168 
0169   using fjcore::PseudoJet::operator*=;
0170   using fjcore::PseudoJet::operator/=;
0171   using fjcore::PseudoJet::operator+=;
0172   using fjcore::PseudoJet::operator-=;
0173 
0174   using fjcore::PseudoJet::user_index;
0175   using fjcore::PseudoJet::set_user_index;
0176   using fjcore::PseudoJet::UserInfoBase;
0177   using fjcore::PseudoJet::InexistentUserInfo;
0178 
0179   using fjcore::PseudoJet::user_info;
0180   using fjcore::PseudoJet::set_user_info;
0181   using fjcore::PseudoJet::has_user_info;
0182   using fjcore::PseudoJet::user_info_ptr;
0183   using fjcore::PseudoJet::user_info_shared_ptr;
0184 
0185   using fjcore::PseudoJet::description;
0186   // In principle, these might be okay, but ClusterSequences should
0187   // be made after explicitly transforming to a proper PseudoJet
0188   // using fjcore::PseudoJet::has_associated_cluster_sequence;
0189   // using fjcore::PseudoJet::has_associated_cs;
0190   // using fjcore::PseudoJet::has_valid_cluster_sequence;
0191   // using fjcore::PseudoJet::has_valid_cs;
0192   // using fjcore::PseudoJet::associated_cluster_sequence;
0193   // using fjcore::PseudoJet::associated_cs;
0194   // using fjcore::PseudoJet::validated_cluster_sequence;
0195   // using fjcore::PseudoJet::validated_cs;
0196   // using fjcore::PseudoJet::set_structure_shared_ptr;
0197   // using fjcore::PseudoJet::has_structure;
0198   // using fjcore::PseudoJet::structure_ptr;
0199   // using fjcore::PseudoJet::structure_non_const_ptr;
0200   // using fjcore::PseudoJet::validated_structure_ptr;
0201   // using fjcore::PseudoJet::structure_shared_ptr;
0202   // ... more
0203 
0204 public:
0205   JetScapeParticleBase() : PseudoJet(){};
0206   JetScapeParticleBase(int label, int id, int stat, const FourVector &p,
0207                        const FourVector &x);
0208   JetScapeParticleBase(int label, int id, int stat, double pt, double eta,
0209                        double phi, double e, double *x = 0);
0210   JetScapeParticleBase(int label, int id, int stat, const FourVector &p,
0211                        const FourVector &x, double mass);
0212   JetScapeParticleBase(const JetScapeParticleBase &srp);
0213 
0214   virtual ~JetScapeParticleBase();
0215 
0216   void clear();
0217 
0218   // Setters
0219   void set_label(int label);
0220   void set_id(int id);
0221   void set_stat(int stat);
0222   void set_x(double x[4]);
0223 
0224   void init_jet_v();
0225   void set_jet_v(double v[4]);
0226   void set_jet_v(FourVector j);
0227 
0228   /** Set a new responsible (Eloss) module
0229      * @return false if we already had one */
0230   bool SetController(string controller = "") {
0231     bool wascontrolled = controlled_;
0232     controlled_ = true;
0233     controller_ = controller;
0234     return wascontrolled;
0235   };
0236   /** Relinquish responsibility of an (Eloss) module */
0237   void UnsetController() {
0238     controller_ = "";
0239     controlled_ = false;
0240   };
0241 
0242   //  Getters
0243 
0244   const int pid() const;
0245   const int pstat() const;
0246   const int plabel() const;
0247   // const double e();
0248   // const double pt();
0249   const double time() const;
0250 
0251   std::vector<JetScapeParticleBase> parents();
0252 
0253   const FourVector p_in() const;
0254   const FourVector &x_in() const;
0255   const FourVector &jet_v() const;
0256 
0257   const double restmass();
0258   const double p(int i);
0259   double pl();
0260   const double nu();
0261   const double t_max();
0262 
0263   virtual JetScapeParticleBase &operator=(JetScapeParticleBase &c);
0264   virtual JetScapeParticleBase &operator=(const JetScapeParticleBase &c);
0265 
0266   /** Check id of responsible (Eloss) module */
0267   string GetController() const { return controller_; };
0268   /** Check whether we have a responsible (Eloss) module */
0269   bool GetControlled() const { return controlled_; };
0270 
0271   // give it a static pythia to look up particle properties
0272   // Be a bit careful with it!
0273   // Init is never called, and this object is not configured. All it can do is look up
0274   // in its original Data table
0275   static Pythia8::Pythia InternalHelperPythia;
0276 
0277 protected:
0278   void set_restmass(
0279       double
0280           mass_input); ///< shouldn't be called from the outside, needs to be consistent with PID
0281 
0282   int pid_;    ///< particle id
0283   int pstat_;  ///< status of particle
0284   int plabel_; ///< the line number in the event record
0285   double
0286       mass_; ///< rest mass of the particle \todo Only maintain PID, look up mass from PDG
0287 
0288   FourVector x_in_; ///< position of particle
0289   FourVector
0290       jet_v_; ///< jet four vector, without gamma factor (so not really a four vector)
0291 
0292   // give it a static pythia to look up particle properties
0293   // Be a bit careful with it!
0294   // Init is never called, and this object is not configured. All it can do is look up
0295   // in its original Data table
0296   //static Pythia8::Pythia InternalHelperPythia;
0297 
0298   /// check whether a module claimed responsibility of this particle
0299   bool controlled_ = false;
0300   string controller_ = "";
0301 };
0302 // END BASE CLASS
0303 
0304 // Declared outside the class
0305 ostream &operator<<(ostream &output, JetScapeParticleBase &p);
0306 
0307 /**************************************************************************************************/
0308 //  PARTON CLASS
0309 /*************************************************************************************************/
0310 class Parton : public JetScapeParticleBase {
0311 
0312 public:
0313   virtual void set_mean_form_time();
0314   virtual void set_form_time(double form_time);
0315 
0316   virtual double form_time();
0317   virtual const double mean_form_time();
0318   virtual void reset_p(double px, double py, double pz);
0319   virtual void set_color(unsigned int col); ///< sets the color of the parton
0320   virtual void
0321   set_anti_color(unsigned int acol); ///< sets anti-color of the parton
0322   virtual void
0323   set_max_color(unsigned int col); ///< sets the color of the parton
0324   virtual void
0325   set_min_color(unsigned int col); ///< sets the color of the parton
0326   virtual void
0327   set_min_anti_color(unsigned int acol); ///< sets anti-color of the parton
0328   bool isPhoton(
0329       int pid); // Checks to see if the particle is a photon, separate derived class for photons
0330 
0331   Parton(int label, int id, int stat, const FourVector &p, const FourVector &x);
0332   Parton(int label, int id, int stat, double pt, double eta, double phi,
0333          double e, double *x = 0);
0334   Parton(const Parton &srp);
0335 
0336   Parton &operator=(Parton &c);
0337   Parton &operator=(const Parton &c);
0338 
0339   const double t();
0340   void set_t(
0341       double
0342           t); ///< virtuality of particle, \WARNING: rescales the spatial component
0343   unsigned int color();      ///< returns the color of the parton
0344   unsigned int anti_color(); ///< returns the anti-color of the parton
0345   unsigned int max_color();
0346   unsigned int min_color();
0347   unsigned int min_anti_color();
0348 
0349   const int edgeid() const;
0350   void set_edgeid(const int id);
0351 
0352   void set_shower(const shared_ptr<PartonShower> pShower);
0353   void set_shower(const weak_ptr<PartonShower> pShower);
0354   const weak_ptr<PartonShower> shower() const;
0355 
0356   std::vector<Parton> parents();
0357 
0358 protected:
0359   double mean_form_time_;     ///< Mean formation time
0360   double form_time_;          ///< event by event formation time
0361   unsigned int Color_;        ///< Large Nc color of parton
0362   unsigned int antiColor_;    ///< Large Nc anti-color of parton
0363   unsigned int MaxColor_;     ///< the running maximum color
0364   unsigned int MinColor_;     ///< color of the parent
0365   unsigned int MinAntiColor_; ///< anti-color of the parent
0366 
0367   weak_ptr<PartonShower> pShower_; ///< shower that this parton belongs to
0368   int edgeid_;                     ///< Position in the shower graph
0369 
0370   // helpers
0371   void initialize_form_time();
0372   void CheckAcceptability(int id); ///< restrict to a few pids only.
0373 };
0374 
0375 class Hadron : public JetScapeParticleBase {
0376 public:
0377   Hadron(int label, int id, int stat, const FourVector &p, const FourVector &x);
0378   Hadron(int label, int id, int stat, double pt, double eta, double phi,
0379          double e, double *x = 0);
0380   Hadron(int label, int id, int stat, const FourVector &p, const FourVector &x,
0381          double mass);
0382   Hadron(const Hadron &srh);
0383 
0384   Hadron &operator=(Hadron &c);
0385   Hadron &operator=(const Hadron &c);
0386 
0387   void set_decay_width(double width) { width_ = width; }
0388 
0389   double decay_width() { return (width_); }
0390 
0391   /// Hadron may be used to handle electrons, gammas, ... as well
0392   /// In addition, not all generated ids may be in the database
0393   /// Currently, we add these manually. Could also reject outright.
0394   bool CheckOrForceHadron(const int id, const double mass = 0);
0395 
0396   /// Returns true when all x entries of the hadrons are (close to) 0
0397   bool has_no_position();
0398 
0399 protected:
0400   double width_;
0401 };
0402 
0403 class Photon : public Parton {
0404 public:
0405   Photon(int label, int id, int stat, const FourVector &p, const FourVector &x);
0406   Photon(int label, int id, int stat, double pt, double eta, double phi,
0407          double e, double *x = 0);
0408   Photon(const Photon &srh);
0409 
0410   Photon &operator=(Photon &ph);
0411   Photon &operator=(const Photon &ph);
0412 };
0413 
0414 }; // namespace Jetscape
0415 
0416 #endif // JETSCAPEPARTICLES_H