Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JetScapeParticles.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file JetScapeParticles.cc
1 /*******************************************************************************
2  * Copyright (c) The JETSCAPE Collaboration, 2018
3  *
4  * Modular, task-based framework for simulating all aspects of heavy-ion collisions
5  *
6  * For the list of contributors see AUTHORS.
7  *
8  * Report issues at https://github.com/JETSCAPE/JETSCAPE/issues
9  *
10  * or via email to bugs.jetscape@gmail.com
11  *
12  * Distributed under the GNU General Public License 3.0 (GPLv3 or later).
13  * See COPYING for details.
14  ******************************************************************************/
15 
16 // Provides JetScapeParticleBase and derived classes Parton, Hadron
17 
18 #include <iostream>
19 #include <complex>
20 #include <fstream>
21 #include <cmath>
22 #include <assert.h>
23 #include "JetScapeLogger.h"
24 #include "JetScapeParticles.h"
25 #include "JetScapeConstants.h"
26 
27 namespace Jetscape {
28 
29 // Initialize static MakeUniqueHelper.here
30 Pythia8::Pythia JetScapeParticleBase::InternalHelperPythia("IntentionallyEmpty",
31  false);
32 
34 
36  : PseudoJet(srp) {
37  pid_ = srp.pid_;
38  plabel_ = srp.plabel_;
39  pstat_ = srp.pstat_;
40  mass_ = srp.mass_;
41  jet_v_ = srp.jet_v_;
42  x_in_ = srp.x_in_;
43 }
44 
46  double pt, double eta, double phi,
47  double e, double *x) {
48  set_label(label);
49  set_id(id);
50  init_jet_v();
51 
52  assert(InternalHelperPythia.particleData.isParticle(id));
53  set_restmass(InternalHelperPythia.particleData.m0(id));
54 
55  reset_momentum(pt * cos(phi), pt * sin(phi), pt * sinh(eta), e);
56  set_stat(stat);
57 
58  if (x) {
59  set_x(x);
60  } else {
61  // if no x specified in constructor, particle starts at origin
62  double x0[4];
63  x0[0] = 0;
64  x0[1] = 0;
65  x0[2] = 0;
66  x0[3] = 0;
67  set_x(x0);
68  }
69 }
70 
72  const FourVector &p,
73  const FourVector &x) {
74 
75  set_label(label);
76  set_id(id);
77  init_jet_v();
78 
79  assert(InternalHelperPythia.particleData.isParticle(id));
80  if ((std::abs(pid()) == 1) || (std::abs(pid()) == 2) || (std::abs(pid()) == 3)) {
81  set_restmass(0.0);
82  } else {
83  set_restmass(InternalHelperPythia.particleData.m0(id));
84  }
85 
86  reset_momentum(p);
87  x_in_ = x;
88  set_stat(stat);
89 }
90 
92  const FourVector &p,
93  const FourVector &x, double mass) {
94  set_label(label);
95  set_id(id);
96  init_jet_v();
97 
98  reset_momentum(p);
99  x_in_ = x;
100  set_stat(stat);
101 }
102 
104  plabel_ = 0;
105  pid_ = 0;
106  pstat_ = 0;
107  mass_ = -1;
108 }
109 
111 
113 
114 void JetScapeParticleBase::set_stat(int stat) { pstat_ = stat; }
115 
116 void JetScapeParticleBase::set_restmass(double mass_input) {
117  mass_ = mass_input;
118 }
119 
120 // not needed in graph structure
121 
123  //FourVector
124  x_in_.Set(x);
125 }
126 
128 
130 
132 
133 // end setters
134 
135 // start getters
136 const int JetScapeParticleBase::pid() const { return (pid_); }
137 
138 const int JetScapeParticleBase::pstat() const { return (pstat_); }
139 
140 const int JetScapeParticleBase::plabel() const { return (plabel_); }
141 
142 const double JetScapeParticleBase::time() const { return (x_in_.t()); }
143 
145  return (FourVector(px(), py(), pz(), e()));
146 }
147 
148 const FourVector &JetScapeParticleBase::x_in() const { return (x_in_); }
149 
150 const FourVector &JetScapeParticleBase::jet_v() const { return (jet_v_); }
151 
152 const double JetScapeParticleBase::restmass() { return (mass_); }
153 
154 const double JetScapeParticleBase::p(int i) {
156  // cerr << " DON'T USE ME VERY OFTEN!!" << endl;
157  switch (i) {
158  case 0:
159  return e();
160  case 1:
161  return px();
162  case 2:
163  return py();
164  case 3:
165  return pz();
166  default:
167  throw std::runtime_error(
168  "JetScapeParticleBase::p(int i) : i is out of bounds.");
169  }
170 }
171 
173  // Have to catch the ones initialized to 0
174  if (jet_v_.comp(0) < 1e-6) {
175  return (std::sqrt(px() * px() + py() * py() + pz() * pz()));
176  }
177 
178  if (jet_v_.comp(0) < 0.99) {
179  // this should never happen
180  cerr << "jet_v_ = " << jet_v_.comp(0) << " " << jet_v_.comp(1) << " "
181  << jet_v_.comp(2) << " " << jet_v_.comp(3) << endl;
182  throw std::runtime_error(
183  "JetScapeParticleBase::pl() : jet_v should never be space-like.");
184  return (-1);
185  } else {
186  // projection onto (unit) jet velocity
187  return (px() * jet_v_.x() + py() * jet_v_.y() + pz() * jet_v_.z()) /
188  std::sqrt(pow(jet_v_.x(), 2) + pow(jet_v_.y(), 2) +
189  pow(jet_v_.z(), 2));
190  }
191 }
192 
193 const double JetScapeParticleBase::nu() {
194  return ((this->e() + std::abs(this->pl())) / std::sqrt(2));
195 }
196 
199 
200  pid_ = c.pid();
201  pstat_ = c.pstat();
202  plabel_ = c.plabel();
203 
204  x_in_ = c.x_in();
205  mass_ = c.mass_;
206 
207  return *this;
208 }
209 
213 
214  pid_ = c.pid_;
215  pstat_ = c.pstat_;
216  plabel_ = c.plabel_;
217 
218  x_in_ = c.x_in_;
219 
220  mass_ = c.mass_;
221  return *this;
222 }
223 
224 ostream &operator<<(ostream &output, JetScapeParticleBase &p) {
225  output << p.plabel() << " " << p.pid() << " " << p.pstat() << " ";
226  // output<<p.pt()<<" "<< (fabs (p.rap())>1e-15?p.rap():0)<<" "<< p.phi() <<" "<<p.e()<<" ";
227  output << p.pt() << " " << (fabs(p.eta()) > 1e-15 ? p.eta() : 0) << " "
228  << p.phi() << " " << p.e() << " ";
229  output << p.x_in().x() << " " << p.x_in().y() << " " << p.x_in().z() << " "
230  << p.x_in().t(); //<<endl;
231 
232  return output;
233 }
234 
235 // ---------------
236 // Parton specific
237 // ---------------
240  form_time_ = srp.form_time_;
241  Color_ = srp.Color_;
242  antiColor_ = srp.antiColor_;
243  MaxColor_ = srp.MaxColor_;
244  MinColor_ = srp.MinColor_;
246 
247  set_edgeid(srp.edgeid());
248  set_shower(srp.shower());
249 
250  // set_edgeid( -1 ); // by default do NOT copy the shower or my position in it
251  // pShower_ = nullptr;
252 }
253 
254 Parton::Parton(int label, int id, int stat, const FourVector &p,
255  const FourVector &x)
256  : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, p, x) {
257  CheckAcceptability(id);
258  assert(InternalHelperPythia.particleData.isParton(id) || isPhoton(id));
260  set_color(0);
261  set_anti_color(0);
262  set_min_color(0);
264  set_max_color(0);
265  set_edgeid(-1);
266  set_shower(0);
267 
268  // cout << "========================== std Ctor called, returning : " << endl << *this << endl;
269 }
270 
271 Parton::Parton(int label, int id, int stat, double pt, double eta, double phi,
272  double e, double *x)
273  : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, pt, eta, phi,
274  e, x) {
275  CheckAcceptability(id);
276  assert(InternalHelperPythia.particleData.isParton(id) || isPhoton(id));
278  set_color(0);
279  set_anti_color(0);
280  set_min_color(0);
282  set_max_color(0);
283  set_edgeid(-1);
284  set_shower(0);
285 
286  // cout << "========================== phieta Ctor called, returning : " << endl << *this << endl;
287 }
288 
290  switch (id) {
291  case 1: //down quark
292  case -1: // anti-down quark
293  break;
294  case 2: // up quark
295  case -2: // anti-up quark
296  break;
297  case 3: // strange quark
298  case -3: // anti-strange quark
299  break;
300  case 4: // charm quark
301  case -4: // anti-charm quark
302  break;
303  case 5: // bottom quark
304  case -5: // anti-bottom quark
305  break;
306  case 21: // gluon
307  break;
308  case 22: // photon
309  break;
310  default:
311  JSWARN << " error in id = " << id;
312  throw std::runtime_error("pid not accepted for Parton");
313  break;
314  }
315 }
316 
320  Color_ = c.Color_;
322  set_edgeid(c.edgeid());
323  set_shower(c.shower());
324 
325  return *this;
326 }
327 
331  Color_ = c.Color_;
333  set_edgeid(c.edgeid());
334  set_shower(c.shower());
335 
336  return *this;
337 }
338 
340  mean_form_time_ = 2.0 * e() / (t() + rounding_error) / fmToGeVinv;
341 }
342 
343 void Parton::set_form_time(double form_time) { form_time_ = form_time; }
344 
346 
347 double Parton::form_time() { return (form_time_); }
348 
349 const double Parton::mean_form_time() { return (mean_form_time_); }
350 
351 const double Parton::t() {
353  // double t_parton = PseudoJet::m2() - restmass()*restmass() ;
354 
355  double t_parton = 0.0;
356  t_parton = e() * e() - px() * px() - py() * py() - pz() * pz() -
357  restmass() * restmass();
358  if (t_parton < 0.0) {
359  // JSWARN << " Virtuality is negative, MATTER cannot handle these particles " << " t = " << t_parton;
360  // JSWARN << " pid = "<< pid() << " E = " << e() << " px = " << px() << " py = " << py() << " pz = " << pz() ;
361  }
362  return (t_parton);
363  // return (t_) ;
364 }
365 
366 void Parton::set_t(double t) {
367  // This function has a very specific purpose and shouldn't normally be used
368  // It scales down p! So catch people trying.
369  if (form_time() >= 0.0) {
370  throw std::runtime_error(
371  "Trying to set virtuality on a normal parton. You almost certainly "
372  "don't want to do that. Please contact the developers if you do.");
373  }
374 
375  // Reset the momentum due to virtuality
376  double newPl = std::sqrt(e() * e() - t - restmass() * restmass());
377  double velocityMod =
378  std::sqrt(std::pow(jet_v_.comp(1), 2) + std::pow(jet_v_.comp(2), 2) +
379  std::pow(jet_v_.comp(3), 2));
380 
381  newPl = newPl / velocityMod;
382  // double newP[4];
383  // newP[0] = e();
384  // for(int j=1;j<=3;j++) {
385  // newP[j] = newPl*jet_v_.comp(j);
386  // }
387  reset_momentum(newPl * jet_v_.comp(1), newPl * jet_v_.comp(2),
388  newPl * jet_v_.comp(3), e());
389 }
390 
391 void Parton::reset_p(double px, double py, double pz) {
392  reset_momentum(px, py, pz, e());
393 }
394 
395 void Parton::set_color(unsigned int col) { Color_ = col; }
396 
397 void Parton::set_anti_color(unsigned int acol) { antiColor_ = acol; }
398 
399 void Parton::set_max_color(unsigned int col) { MaxColor_ = col; }
400 
401 void Parton::set_min_color(unsigned int col) { MinColor_ = col; }
402 
403 void Parton::set_min_anti_color(unsigned int acol) { MinAntiColor_ = acol; }
404 
405 const int Parton::edgeid() const { return (edgeid_); }
406 
407 void Parton::set_edgeid(const int id) { edgeid_ = id; }
408 
410  if (pShower != nullptr)
411  pShower_ = pShower;
412 }
413 
414 void Parton::set_shower(const weak_ptr<PartonShower> pShower) {
415  pShower_ = pShower;
416 }
417 
418 const weak_ptr<PartonShower> Parton::shower() const { return pShower_; }
419 
420 std::vector<Parton> Parton::parents() {
421  std::vector<Parton> ret;
422  auto shower = pShower_.lock();
423  if (!shower)
424  return ret;
425  node root = shower->GetEdgeAt(edgeid_).source();
426  for (node::in_edges_iterator parent = root.in_edges_begin();
427  parent != root.in_edges_end(); ++parent) {
428  ret.push_back(*shower->GetParton(*parent));
429  }
430  return ret;
431 }
432 
433 unsigned int Parton::color() { return (Color_); }
434 
435 unsigned int Parton::anti_color() { return (antiColor_); }
436 
437 unsigned int Parton::min_color() { return (MinColor_); }
438 
439 unsigned int Parton::min_anti_color() { return (MinAntiColor_); }
440 
441 unsigned int Parton::max_color() { return (MaxColor_); }
442 
444  if (pid == photonid)
445  return true;
446  return false;
447 }
448 // ---------------
449 // Hadron specific
450 // ---------------
451 
454  width_ = srh.width_;
455 }
456 
457 Hadron::Hadron(int label, int id, int stat, const FourVector &p,
458  const FourVector &x)
459  : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, p, x) {
461  // assert ( InternalHelperPythia.particleData.isHadron(id) );
462  set_decay_width(0.1);
463 }
464 
465 Hadron::Hadron(int label, int id, int stat, double pt, double eta, double phi,
466  double e, double *x)
467  : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, pt, eta, phi,
468  e, x) {
470  // assert ( InternalHelperPythia.particleData.isHadron(id) );
471  set_decay_width(0.1);
472  // cout << "========================== phieta Ctor called, returning : " << endl << *this << endl;
473 }
474 
475 Hadron::Hadron(int label, int id, int stat, const FourVector &p,
476  const FourVector &x, double mass)
477  : JetScapeParticleBase::JetScapeParticleBase(label, id, stat, p, x, mass) {
478  assert(CheckOrForceHadron(id, mass));
479  set_restmass(mass);
480 }
481 
482 bool Hadron::CheckOrForceHadron(const int id, const double mass) {
483  bool status = InternalHelperPythia.particleData.isHadron(id);
484  if (status)
485  return true;
486 
487  // If it's not recognized as a hadron, still allow some (or all)
488  // particles. Particularly leptons and gammas are the point here.
489  // TODO: Handle non-partonic non-hadrons more gracefully
490 
491  // -- Add unknown particles
492  if (!InternalHelperPythia.particleData.isParticle(
493  id)) { // avoid doing it over and over
494  JSWARN << "id = " << id << " is not recognized as a hadron! "
495  << "Add it as a new type of particle.";
496  InternalHelperPythia.particleData.addParticle(id, " ", 0, 0, 0, mass, 0.1);
497  }
498 
499  // -- now all that's left is known non-hadrons. We'll just accept those.
500  return true;
501 }
502 
504  return (x_in_.t() < 1e-6) &&
505  (x_in_.x() < 1e-6) &&
506  (x_in_.y() < 1e-6) &&
507  (x_in_.z() < 1e-6);
508 }
509 
512  width_ = c.width_;
513  return *this;
514 }
515 
518  width_ = c.width_;
519  return *this;
520 }
521 
522 // ---------------
523 // Photon specific
524 // ---------------
525 
526 Photon::Photon(const Photon &srh) : Parton::Parton(srh) {}
527 
528 Photon::Photon(int label, int id, int stat, const FourVector &p,
529  const FourVector &x)
530  : Parton::Parton(label, id, stat, p, x) {}
531 
532 Photon::Photon(int label, int id, int stat, double pt, double eta, double phi,
533  double e, double *x)
534  : Parton::Parton(label, id, stat, pt, eta, phi, e, x) {}
535 
537  Parton::operator=(ph);
538  return *this;
539 }
540 
542  Parton::operator=(ph);
543  return *this;
544 }
545 
546 } // namespace Jetscape