FairRoot/PandaRoot
PythiaChiGen.cxx
Go to the documentation of this file.
1 /*
2  * @author Alexey Luchinsky
3  * @author Stanislav Poslavsky (stvlpos (at) mail.ru)
4  */
5 
6 #include <boost/random/mersenne_twister.hpp>
7 
8 #include "PythiaChiGen.h"
9 #include "EvtGenBase/EvtParticleFactory.hh"
10 #include "EvtGenBase/EvtParticle.hh"
11 #include "TError.h"
12 
13 using namespace Pythia8;
14 using namespace std;
15 
17  PartonicModel& partonicModelRef, int tries, bool hadronize)
18 : partonicModel(partonicModelRef) {
20  eCM = partonicModelRef.eCM;
21  protonPz = sqrt(pow2(eCM) / 4 - 1);
22  maxTries = tries;
23  doHadronization = hadronize;
24 }
25 
27 }
28 
29 int chigen::PythiaChiGen::COLORS[] = {101, 102, 103};
30 
32 
33  double pT = sqrt(partonicModel.uH * partonicModel.tH / partonicModel.sH);
34  double pL = (partonicModel.tH - partonicModel.uH) / (2 * sqrt(partonicModel.sH));
35  double mesonE = sqrt(partonicModel.mesonMass2 + pow2(pT) + pow2(pL));
36  double gluonE = sqrt(pow2(pT) + pow2(pL));
37 
38 
39  //quarkonia
40  mesonMomentum = Vec4(0., pT, pL, mesonE);
41  //gluon
42  gluonMomentum = Vec4(0., -pT, -pL, gluonE);
43 
44  //rotate vectors in XY plane
45  double hardPhiAngle = chigen::random::random_engine->flat()* 2 * M_PI;
46  mesonMomentum.rot(0, hardPhiAngle);
47  gluonMomentum.rot(0, hardPhiAngle);
48 
49  //boost from hard c.m. to hadronic c.m.
50  boost = Vec4(0., 0., (partonicModel.x1 - partonicModel.x2) * protonPz,
51  (partonicModel.x1 + partonicModel.x2) * protonPz);
52  //do not boost meson momentum until EvtGen perform decay!!!
53  //mesonMomentum.bst(boost) <-- this will destroy polarization
54  gluonMomentum.bst(boost);
55 
56  //remnants kinematics
57  //proton remnants
58  calculateHadronRemnants(partonicModel.x1, protonPz, uMomentum, dMomentum);
59  //antiproton remnants
60  calculateHadronRemnants(partonicModel.x2, -protonPz, ubarMomentum, dbarMomentum);
61 }
62 
63 void chigen::PythiaChiGen::calculateHadronRemnants(double x, double hadronPz, Vec4& u, Vec4& d) {
64 
65  Vec4 totalRemnant(0, 0, (1 - x) * hadronPz, eCM / 2 - x * abs(hadronPz));
66  double halfRemnantInvMass = totalRemnant.mCalc() / 2;
67  //make remnants pT
68  double theta = chigen::random::random_engine->flat() * M_PI;
69  double sine = halfRemnantInvMass * sin(theta), cosine = halfRemnantInvMass * cos(theta);
70  u.p(0, sine, cosine, halfRemnantInvMass);
71  d.p(0, -sine, -cosine, halfRemnantInvMass);
72 
73  //rotate vectors in XY plane
74  double phi = chigen::random::random_engine->flat()* 2 * M_PI;
75  u.rot(0, phi);
76  d.rot(0, phi);
77 
78  //boost to lab frame
79  u.bst(totalRemnant);
80  d.bst(totalRemnant);
81 }
82 
83 void chigen::PythiaChiGen::decay(Event& event) {
84  //lets decay polarized meson via EvtGen
85  EvtVector4R chiMomentum(
86  mesonMomentum.e(),
87  mesonMomentum.px(),
88  mesonMomentum.py(),
89  mesonMomentum.pz());
90 
91 
92  EvtParticle *chiMeson =
93  EvtParticleFactory::particleFactory(partonicModel.evtId, chiMomentum);
94  chiMeson->setSpinDensityForward(partonicModel.spinDensity);
95 
96  //decay
97  chigen::evtgen::evt_gen->generateDecay(chiMeson);
98  //write info
99  evtstdhep.init();
100  chiMeson->makeStdHep(evtstdhep);
101 
102  assert(evtstdhep.getNPart() == 5);
103  int id;
104  EvtVector4R vertexPoint, evtMomentum;
105  for (int particleNumber = 0, size = evtstdhep.getNPart();
106  particleNumber < size; ++particleNumber) {
107  vertexPoint = evtstdhep.getX4(particleNumber);
108  evtMomentum = evtstdhep.getP4(particleNumber);
109 
110  Pythia8::Particle p;
111  p.id(id = evtstdhep.getStdHepID(particleNumber));
112  p.px(evtMomentum.get(1));
113  p.py(evtMomentum.get(2));
114  p.pz(evtMomentum.get(3));
115  p.e(evtMomentum.get(0));
116  //boost from hard c.m. frame to hadronic c.m. frame
117  p.bst(boost);
118 
119  p.daughter1(evtstdhep.getFirstDaughter(particleNumber) + 1);
120  p.daughter2(evtstdhep.getLastDaughter(particleNumber) + 1);
121  p.mother1(evtstdhep.getFirstMother(particleNumber) + 1);
122  p.mother2(evtstdhep.getLastMother(particleNumber) + 1);
123  if (chigen::isCharmonia(id))
124  p.status(-33);
125  else
126  p.status(91);
127 
128  event.append(p);
129  }
130 }
131 
133  // first setup colors and anti-colors
134  // the following color mask is adopted:
135  //
136  // u (bar) d (bar) g
137  // color : 101 102 103
138  // anti-color: COLORS[0] COLORS[1] COLORS[2]
139 
140  // randomly shuffle colors
141  std::random_shuffle(COLORS, COLORS + 3); //todo use same seed as in rndm
142 
143  //already added chi-meson in decay()
144  // //filling the event record:
145  // //quarkonia
146  // event.append(partonicModel->pdgId/*id*/, 21 /*status code*/,
147  // 0, 0/*colors*/,
148  // mesonMomentum /*4-momentum*/, partonicModel->mesonMass /*mass*/);
149 
150  //gluon
151  event.append(21/*id*/, 23 /*status code (should be hadronized)*/,
152  103, COLORS[2]/*colors*/,
153  gluonMomentum /*4-momentum*/, 0.0 /*mass*/);
154 
155 
156  //u-quark
157  event.append(2/*id*/, 23 /*status code (should be hadronized)*/,
158  101, 0/*colors*/,
159  uMomentum/*4-momentum*/, 0.0/* mass*/);
160 
161  //d-quark
162  event.append(1/*id*/, 23 /*status code (should be hadronized)*/,
163  102, 0/*colors*/,
164  dMomentum/*4-momentum*/, 0.0/* mass*/);
165 
166  //u-bar
167  event.append(-2/*id*/, 23 /*status code (should be hadronized)*/,
168  0, COLORS[0]/*colors*/,
169  ubarMomentum/*4-momentum*/, 0.0/* mass*/);
170 
171  //d-bar
172  event.append(-1/*id*/, 23 /*status code (should be hadronized)*/,
173  0, COLORS[1]/*colors*/,
174  dbarMomentum/*4-momentum*/, 0.0 /*mass*/);
175 }
176 
178  Event& event = chigen::pythia::pythia->event;
179  //reset event is necessary
180  event.reset();
181 
182  //number of attempts
183  int attempt = 0;
184  while (!partonicModel.next() && attempt++ < maxTries);
185  //parton level failed
186  if (attempt >= maxTries)
187  Fatal("PythiaHadronizationModel::next", "Can't set kinematics at parton level.");
188 
189  attempt = 0;
190  calculateKinematics();
191  decay(event);
192  fillColorEvent(event);
193 
194  if (doHadronization) {
195  while (!chigen::pythia::pythia->next() && attempt++ < maxTries) {
196  event.reset();
197  calculateKinematics();
198  decay(event);
199  fillColorEvent(event);
200  }
201  //hadron level failed
202  if (attempt >= maxTries)
203  Fatal("PythiaHadronizationModel::next", "Failed to hadronize remnants.");
204  }
205  return &event;
206 }
207 
Double_t p
Definition: anasim.C:58
void ensure_chigen_is_initialized()
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
bool isCharmonia(int pdgCode)
static int COLORS[]
Definition: PythiaChiGen.h:92
TObjArray * d
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
PythiaChiGen(PartonicModel &partonicModel, int maxTries=30, bool doHadronization=true)
void calculateHadronRemnants(double x, double hadronPz, Vec4 &u, Vec4 &d)
Double_t x
void fillColorEvent(Event &event)
ClassImp(PndAnaContFact)
void decay(Event &event)
Pythia8::Pythia * pythia
static int next[96]
Definition: ranlxd.cxx:374
ChiGenRandomEngine * random_engine