Back to home page

sPhenix code displayed by LXR

 
 

    


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

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 #include <iostream>
0019 #include <complex>
0020 #include <fstream>
0021 #include <cmath>
0022 #include <assert.h>
0023 #include "JetScapeLogger.h"
0024 #include "JetScapeParticles.h"
0025 #include "JetScapeConstants.h"
0026 
0027 namespace Jetscape {
0028 
0029 // Initialize static MakeUniqueHelper.here
0030 Pythia8::Pythia JetScapeParticleBase::InternalHelperPythia("IntentionallyEmpty",
0031                                                            false);
0032 
0033 JetScapeParticleBase::~JetScapeParticleBase() { VERBOSESHOWER(9); }
0034 
0035 JetScapeParticleBase::JetScapeParticleBase(const JetScapeParticleBase &srp)
0036     : PseudoJet(srp) {
0037   pid_ = srp.pid_;
0038   plabel_ = srp.plabel_;
0039   pstat_ = srp.pstat_;
0040   mass_ = srp.mass_;
0041   jet_v_ = srp.jet_v_;
0042   x_in_ = srp.x_in_;
0043 }
0044 
0045 JetScapeParticleBase::JetScapeParticleBase(int label, int id, int stat,
0046                                            double pt, double eta, double phi,
0047                                            double e, double *x) {
0048   set_label(label);
0049   set_id(id);
0050   init_jet_v();
0051 
0052   assert(InternalHelperPythia.particleData.isParticle(id));
0053   set_restmass(InternalHelperPythia.particleData.m0(id));
0054 
0055   reset_momentum(pt * cos(phi), pt * sin(phi), pt * sinh(eta), e);
0056   set_stat(stat);
0057 
0058   if (x) {
0059     set_x(x);
0060   } else {
0061     // if no x specified in constructor, particle starts at origin
0062     double x0[4];
0063     x0[0] = 0;
0064     x0[1] = 0;
0065     x0[2] = 0;
0066     x0[3] = 0;
0067     set_x(x0);
0068   }
0069 }
0070 
0071 JetScapeParticleBase::JetScapeParticleBase(int label, int id, int stat,
0072                                            const FourVector &p,
0073                                            const FourVector &x) {
0074 
0075   set_label(label);
0076   set_id(id);
0077   init_jet_v();
0078 
0079   assert(InternalHelperPythia.particleData.isParticle(id));
0080   if ((std::abs(pid()) == 1) || (std::abs(pid()) == 2) || (std::abs(pid()) == 3)) {
0081         set_restmass(0.0);
0082   } else {
0083         set_restmass(InternalHelperPythia.particleData.m0(id));
0084   }
0085 
0086   reset_momentum(p);
0087   x_in_ = x;
0088   set_stat(stat);
0089 }
0090 
0091 JetScapeParticleBase::JetScapeParticleBase(int label, int id, int stat,
0092                                            const FourVector &p,
0093                                            const FourVector &x, double mass) {
0094   set_label(label);
0095   set_id(id);
0096   init_jet_v();
0097 
0098   reset_momentum(p);
0099   x_in_ = x;
0100   set_stat(stat);
0101 }
0102 
0103 void JetScapeParticleBase::clear() {
0104   plabel_ = 0;
0105   pid_ = 0;
0106   pstat_ = 0;
0107   mass_ = -1;
0108 }
0109 
0110 void JetScapeParticleBase::set_label(int label) { plabel_ = label; }
0111 
0112 void JetScapeParticleBase::set_id(int id) { pid_ = id; }
0113 
0114 void JetScapeParticleBase::set_stat(int stat) { pstat_ = stat; }
0115 
0116 void JetScapeParticleBase::set_restmass(double mass_input) {
0117   mass_ = mass_input;
0118 }
0119 
0120 // not needed in graph structure
0121 
0122 void JetScapeParticleBase::set_x(double x[4]) {
0123   //FourVector
0124   x_in_.Set(x);
0125 }
0126 
0127 void JetScapeParticleBase::init_jet_v() { jet_v_ = FourVector(); }
0128 
0129 void JetScapeParticleBase::set_jet_v(double v[4]) { jet_v_ = FourVector(v); }
0130 
0131 void JetScapeParticleBase::set_jet_v(FourVector j) { jet_v_ = j; }
0132 
0133 //  end setters
0134 
0135 //  start getters
0136 const int JetScapeParticleBase::pid() const { return (pid_); }
0137 
0138 const int JetScapeParticleBase::pstat() const { return (pstat_); }
0139 
0140 const int JetScapeParticleBase::plabel() const { return (plabel_); }
0141 
0142 const double JetScapeParticleBase::time() const { return (x_in_.t()); }
0143 
0144 const FourVector JetScapeParticleBase::p_in() const {
0145   return (FourVector(px(), py(), pz(), e()));
0146 }
0147 
0148 const FourVector &JetScapeParticleBase::x_in() const { return (x_in_); }
0149 
0150 const FourVector &JetScapeParticleBase::jet_v() const { return (jet_v_); }
0151 
0152 const double JetScapeParticleBase::restmass() { return (mass_); }
0153 
0154 const double JetScapeParticleBase::p(int i) {
0155   /// Deprecated. Prefer explicit component access
0156   // cerr << " DON'T USE ME VERY OFTEN!!" << endl;
0157   switch (i) {
0158   case 0:
0159     return e();
0160   case 1:
0161     return px();
0162   case 2:
0163     return py();
0164   case 3:
0165     return pz();
0166   default:
0167     throw std::runtime_error(
0168         "JetScapeParticleBase::p(int i) : i is out of bounds.");
0169   }
0170 }
0171 
0172 double JetScapeParticleBase::pl() {
0173   // Have to catch the ones initialized to 0
0174   if (jet_v_.comp(0) < 1e-6) {
0175     return (std::sqrt(px() * px() + py() * py() + pz() * pz()));
0176   }
0177 
0178   if (jet_v_.comp(0) < 0.99) {
0179     // this should never happen
0180     cerr << "jet_v_ = " << jet_v_.comp(0) << "  " << jet_v_.comp(1) << "  "
0181          << jet_v_.comp(2) << "  " << jet_v_.comp(3) << endl;
0182     throw std::runtime_error(
0183         "JetScapeParticleBase::pl() : jet_v should never be space-like.");
0184     return (-1);
0185   } else {
0186     // projection onto (unit) jet velocity
0187     return (px() * jet_v_.x() + py() * jet_v_.y() + pz() * jet_v_.z()) /
0188            std::sqrt(pow(jet_v_.x(), 2) + pow(jet_v_.y(), 2) +
0189                      pow(jet_v_.z(), 2));
0190   }
0191 }
0192 
0193 const double JetScapeParticleBase::nu() {
0194   return ((this->e() + std::abs(this->pl())) / std::sqrt(2));
0195 }
0196 
0197 JetScapeParticleBase &JetScapeParticleBase::operator=(JetScapeParticleBase &c) {
0198   fjcore::PseudoJet::operator=(c);
0199 
0200   pid_ = c.pid();
0201   pstat_ = c.pstat();
0202   plabel_ = c.plabel();
0203 
0204   x_in_ = c.x_in();
0205   mass_ = c.mass_;
0206 
0207   return *this;
0208 }
0209 
0210 JetScapeParticleBase &
0211 JetScapeParticleBase::operator=(const JetScapeParticleBase &c) {
0212   fjcore::PseudoJet::operator=(c);
0213 
0214   pid_ = c.pid_;
0215   pstat_ = c.pstat_;
0216   plabel_ = c.plabel_;
0217 
0218   x_in_ = c.x_in_;
0219 
0220   mass_ = c.mass_;
0221   return *this;
0222 }
0223 
0224 ostream &operator<<(ostream &output, JetScapeParticleBase &p) {
0225   output << p.plabel() << " " << p.pid() << " " << p.pstat() << " ";
0226   // output<<p.pt()<<" "<< (fabs (p.rap())>1e-15?p.rap():0)<<" "<< p.phi() <<" "<<p.e()<<" ";
0227   output << p.pt() << " " << (fabs(p.eta()) > 1e-15 ? p.eta() : 0) << " "
0228          << p.phi() << " " << p.e() << " ";
0229   output << p.x_in().x() << " " << p.x_in().y() << " " << p.x_in().z() << " "
0230          << p.x_in().t(); //<<endl;
0231 
0232   return output;
0233 }
0234 
0235 // ---------------
0236 // Parton specific
0237 // ---------------
0238 Parton::Parton(const Parton &srp)
0239     : JetScapeParticleBase::JetScapeParticleBase(srp) {
0240   form_time_ = srp.form_time_;
0241   Color_ = srp.Color_;
0242   antiColor_ = srp.antiColor_;
0243   MaxColor_ = srp.MaxColor_;
0244   MinColor_ = srp.MinColor_;
0245   MinAntiColor_ = srp.MinAntiColor_;
0246 
0247   set_edgeid(srp.edgeid());
0248   set_shower(srp.shower());
0249 
0250   // set_edgeid( -1 ); // by default do NOT copy the shower or my position in it
0251   // pShower_ = nullptr;
0252 }
0253 
0254 Parton::Parton(int label, int id, int stat, const FourVector &p,
0255                const FourVector &x)
0256     : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, p, x) {
0257   CheckAcceptability(id);
0258   assert(InternalHelperPythia.particleData.isParton(id) || isPhoton(id));
0259   initialize_form_time();
0260   set_color(0);
0261   set_anti_color(0);
0262   set_min_color(0);
0263   set_min_anti_color(0);
0264   set_max_color(0);
0265   set_edgeid(-1);
0266   set_shower(0);
0267 
0268   // cout << "========================== std Ctor called, returning : " << endl << *this << endl;
0269 }
0270 
0271 Parton::Parton(int label, int id, int stat, double pt, double eta, double phi,
0272                double e, double *x)
0273     : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, pt, eta, phi,
0274                                                  e, x) {
0275   CheckAcceptability(id);
0276   assert(InternalHelperPythia.particleData.isParton(id) || isPhoton(id));
0277   initialize_form_time();
0278   set_color(0);
0279   set_anti_color(0);
0280   set_min_color(0);
0281   set_min_anti_color(0);
0282   set_max_color(0);
0283   set_edgeid(-1);
0284   set_shower(0);
0285 
0286   // cout << "========================== phieta Ctor called, returning : " << endl << *this << endl;
0287 }
0288 
0289 void Parton::CheckAcceptability(int id) {
0290   switch (id) {
0291   case 1:  //down quark
0292   case -1: // anti-down quark
0293     break;
0294   case 2:  // up quark
0295   case -2: // anti-up quark
0296     break;
0297   case 3:  // strange quark
0298   case -3: // anti-strange quark
0299     break;
0300   case 4:  // charm quark
0301   case -4: // anti-charm quark
0302     break;
0303   case 5:  // bottom quark
0304   case -5: // anti-bottom quark
0305     break;
0306   case 21: // gluon
0307     break;
0308   case 22: // photon
0309     break;
0310   default:
0311     JSWARN << " error in id = " << id;
0312     throw std::runtime_error("pid not accepted for Parton");
0313     break;
0314   }
0315 }
0316 
0317 Parton &Parton::operator=(Parton &c) {
0318   JetScapeParticleBase::operator=(c);
0319   form_time_ = c.form_time_;
0320   Color_ = c.Color_;
0321   antiColor_ = c.antiColor_;
0322   set_edgeid(c.edgeid());
0323   set_shower(c.shower());
0324 
0325   return *this;
0326 }
0327 
0328 Parton &Parton::operator=(const Parton &c) {
0329   JetScapeParticleBase::operator=(c);
0330   form_time_ = c.form_time_;
0331   Color_ = c.Color_;
0332   antiColor_ = c.antiColor_;
0333   set_edgeid(c.edgeid());
0334   set_shower(c.shower());
0335 
0336   return *this;
0337 }
0338 
0339 void Parton::set_mean_form_time() {
0340   mean_form_time_ = 2.0 * e() / (t() + rounding_error) / fmToGeVinv;
0341 }
0342 
0343 void Parton::set_form_time(double form_time) { form_time_ = form_time; }
0344 
0345 void Parton::initialize_form_time() { form_time_ = -0.1; }
0346 
0347 double Parton::form_time() { return (form_time_); }
0348 
0349 const double Parton::mean_form_time() { return (mean_form_time_); }
0350 
0351 const double Parton::t() {
0352   /// \Todo: Fix
0353   //  double t_parton = PseudoJet::m2()  - restmass()*restmass() ;
0354 
0355   double t_parton = 0.0;
0356   t_parton = e() * e() - px() * px() - py() * py() - pz() * pz() -
0357              restmass() * restmass();
0358   if (t_parton < 0.0) {
0359     // JSWARN << " Virtuality is negative, MATTER cannot handle these particles " << " t = " << t_parton;
0360     // JSWARN << " pid = "<< pid() << " E = " << e() << " px = " << px() << " py = " << py() << " pz = " << pz() ;
0361   }
0362   return (t_parton);
0363   // return (t_) ;
0364 }
0365 
0366 void Parton::set_t(double t) {
0367   // This function has a very specific purpose and shouldn't normally be used
0368   // It scales down p! So catch people trying.
0369   if (form_time() >= 0.0) {
0370     throw std::runtime_error(
0371         "Trying to set virtuality on a normal parton. You almost certainly "
0372         "don't want to do that. Please contact the developers if you do.");
0373   }
0374 
0375   //  Reset the momentum due to virtuality
0376   double newPl = std::sqrt(e() * e() - t - restmass() * restmass());
0377   double velocityMod =
0378       std::sqrt(std::pow(jet_v_.comp(1), 2) + std::pow(jet_v_.comp(2), 2) +
0379                 std::pow(jet_v_.comp(3), 2));
0380 
0381   newPl = newPl / velocityMod;
0382   // double newP[4];
0383   // newP[0] = e();
0384   // for(int j=1;j<=3;j++) {
0385   //   newP[j] = newPl*jet_v_.comp(j);
0386   // }
0387   reset_momentum(newPl * jet_v_.comp(1), newPl * jet_v_.comp(2),
0388                  newPl * jet_v_.comp(3), e());
0389 }
0390 
0391 void Parton::reset_p(double px, double py, double pz) {
0392   reset_momentum(px, py, pz, e());
0393 }
0394 
0395 void Parton::set_color(unsigned int col) { Color_ = col; }
0396 
0397 void Parton::set_anti_color(unsigned int acol) { antiColor_ = acol; }
0398 
0399 void Parton::set_max_color(unsigned int col) { MaxColor_ = col; }
0400 
0401 void Parton::set_min_color(unsigned int col) { MinColor_ = col; }
0402 
0403 void Parton::set_min_anti_color(unsigned int acol) { MinAntiColor_ = acol; }
0404 
0405 const int Parton::edgeid() const { return (edgeid_); }
0406 
0407 void Parton::set_edgeid(const int id) { edgeid_ = id; }
0408 
0409 void Parton::set_shower(const shared_ptr<PartonShower> pShower) {
0410   if (pShower != nullptr)
0411     pShower_ = pShower;
0412 }
0413 
0414 void Parton::set_shower(const weak_ptr<PartonShower> pShower) {
0415   pShower_ = pShower;
0416 }
0417 
0418 const weak_ptr<PartonShower> Parton::shower() const { return pShower_; }
0419 
0420 std::vector<Parton> Parton::parents() {
0421   std::vector<Parton> ret;
0422   auto shower = pShower_.lock();
0423   if (!shower)
0424     return ret;
0425   node root = shower->GetEdgeAt(edgeid_).source();
0426   for (node::in_edges_iterator parent = root.in_edges_begin();
0427        parent != root.in_edges_end(); ++parent) {
0428     ret.push_back(*shower->GetParton(*parent));
0429   }
0430   return ret;
0431 }
0432 
0433 unsigned int Parton::color() { return (Color_); }
0434 
0435 unsigned int Parton::anti_color() { return (antiColor_); }
0436 
0437 unsigned int Parton::min_color() { return (MinColor_); }
0438 
0439 unsigned int Parton::min_anti_color() { return (MinAntiColor_); }
0440 
0441 unsigned int Parton::max_color() { return (MaxColor_); }
0442 
0443 bool Parton::isPhoton(int pid) {
0444   if (pid == photonid)
0445     return true;
0446   return false;
0447 }
0448 // ---------------
0449 // Hadron specific
0450 // ---------------
0451 
0452 Hadron::Hadron(const Hadron &srh)
0453     : JetScapeParticleBase::JetScapeParticleBase(srh) {
0454   width_ = srh.width_;
0455 }
0456 
0457 Hadron::Hadron(int label, int id, int stat, const FourVector &p,
0458                const FourVector &x)
0459     : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, p, x) {
0460   assert(CheckOrForceHadron(id));
0461   // assert ( InternalHelperPythia.particleData.isHadron(id) );
0462   set_decay_width(0.1);
0463 }
0464 
0465 Hadron::Hadron(int label, int id, int stat, double pt, double eta, double phi,
0466                double e, double *x)
0467     : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, pt, eta, phi,
0468                                                  e, x) {
0469   assert(CheckOrForceHadron(id));
0470   // assert ( InternalHelperPythia.particleData.isHadron(id) );
0471   set_decay_width(0.1);
0472   // cout << "========================== phieta Ctor called, returning : " << endl << *this << endl;
0473 }
0474 
0475 Hadron::Hadron(int label, int id, int stat, const FourVector &p,
0476                const FourVector &x, double mass)
0477     : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, p, x, mass) {
0478   assert(CheckOrForceHadron(id, mass));
0479   set_restmass(mass);
0480 }
0481 
0482 bool Hadron::CheckOrForceHadron(const int id, const double mass) {
0483   bool status = InternalHelperPythia.particleData.isHadron(id);
0484   if (status)
0485     return true;
0486 
0487   // If it's not recognized as a hadron, still allow some (or all)
0488   // particles. Particularly leptons and gammas are the point here.
0489   // TODO: Handle non-partonic non-hadrons more gracefully
0490 
0491   // -- Add unknown particles
0492   if (!InternalHelperPythia.particleData.isParticle(
0493           id)) { // avoid doing it over and over
0494     JSWARN << "id = " << id << " is not recognized as a hadron! "
0495            << "Add it as a new type of particle.";
0496     InternalHelperPythia.particleData.addParticle(id, " ", 0, 0, 0, mass, 0.1);
0497   }
0498 
0499   // -- now all that's left is known non-hadrons. We'll just accept those.
0500   return true;
0501 }
0502 
0503 bool Hadron::has_no_position(){
0504   return (x_in_.t() < 1e-6) &&
0505          (x_in_.x() < 1e-6) &&
0506          (x_in_.y() < 1e-6) &&
0507          (x_in_.z() < 1e-6);
0508 }
0509 
0510 Hadron &Hadron::operator=(Hadron &c) {
0511   JetScapeParticleBase::operator=(c);
0512   width_ = c.width_;
0513   return *this;
0514 }
0515 
0516 Hadron &Hadron::operator=(const Hadron &c) {
0517   JetScapeParticleBase::operator=(c);
0518   width_ = c.width_;
0519   return *this;
0520 }
0521 
0522 // ---------------
0523 // Photon specific
0524 // ---------------
0525 
0526 Photon::Photon(const Photon &srh) : Parton::Parton(srh) {}
0527 
0528 Photon::Photon(int label, int id, int stat, const FourVector &p,
0529                const FourVector &x)
0530     : Parton::Parton(label, id, stat, p, x) {}
0531 
0532 Photon::Photon(int label, int id, int stat, double pt, double eta, double phi,
0533                double e, double *x)
0534     : Parton::Parton(label, id, stat, pt, eta, phi, e, x) {}
0535 
0536 Photon &Photon::operator=(Photon &ph) {
0537   Parton::operator=(ph);
0538   return *this;
0539 }
0540 
0541 Photon &Photon::operator=(const Photon &ph) {
0542   Parton::operator=(ph);
0543   return *this;
0544 }
0545 
0546 } // namespace Jetscape