GENIEGenerator
Loading...
Searching...
No Matches
LeptoHadPythia8.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*
3 Copyright (c) 2003-2025, The GENIE Collaboration
4 For the full text of the license visit http://copyright.genie-mc.org
5
6 Alfonso Garcia <aagarciasoto \at km3net.de>
7 IFIC (Valencia)
8*/
9//____________________________________________________________________________
10
12
13int LeptoHadPythia8::getMeson(int q, int qb, double rnd) const {
14 // options: q -> d=1 / u=1
15 // options: qb -> sb=-3 / cb=-4 / bb=-5
16 int aqb = abs(qb);
17 int MultipletCode = ( mesonRateSum[aqb-3]*rnd>1 ) ? 1: 3;
18 int idMeson = 100*aqb + 10*q + MultipletCode;
19 if (qb==-4) return -1*idMeson;
20 else return idMeson;
21}
22
23int LeptoHadPythia8::getBaryon(int qq, int q, double rnd) const {
24 // options: qq -> dd1=1103 / ud0=2101 / ud1=2103 / uu1=2203
25 // options: q -> d=1 / u=2 / s=3 / c=4 / b=5
26 int id1 = qq / 1000;
27 int id2 = (qq / 100) % 10;
28 int id3 = qq % 10;
29 int spin = id3 - 1;
30 if (spin==2 && id1!=id2) spin = 4;
31 if (q!=id1 && q!=id2) spin++;
32 int o1 = TMath::Max( q, TMath::Max( id1, id2) );
33 int o3 = TMath::Min( q, TMath::Min( id1, id2) );
34 int o2 = q + id1 + id2 - o1 - o3;
35 int spinBar = ( CGSum[spin]*rnd<CGOct[spin] ) ? 2 : 4;
36 if ( spinBar==2 && o1>o2 && o2>o3 && id3==1 ) return 1000*o1 + 100*o3 + 10*o2 + spinBar; //lambdas
37 else return 1000*o1 + 100*o2 + 10*o3 + spinBar;
38}
39
40double LeptoHadPythia8::getRandomZ( double a, double b) const {
41 // fragmentation function f(x) = ((1-x)^a*exp(-b/x))/x
42 // not optimal if a->0 or a->1
43 double zpeak = (b+1.-sqrt(pow(b-1.,2)+4.*a*b))/(1.-a)/2.;
44 if ( zpeak>0.9999 && b>100. ) zpeak = TMath::Min(zpeak, 1.-a/b);
45
46 bool closeto0 = ( zpeak<0.1);
47 bool closeto1 = ( zpeak>0.85 && b>1. );
48
49 double flw = 1.;
50 double fup = 1.;
51 double frn = 2.;
52 double wdt = 0.5;
53
54 if ( closeto0 ) {
55 wdt = 2.75*zpeak;
56 flw = wdt;
57 fup = -wdt*log(wdt);
58 frn = flw+fup;
59 }
60 else if ( closeto1 ) {
61 double rcb = sqrt(4.+pow(1./b,2));
62 wdt = rcb - 1./zpeak - (1./b)*log(zpeak*(rcb+1./b)/2. );
63 wdt += (a/b)*log(1.-zpeak);
64 wdt = TMath::Min(zpeak,TMath::Max(0.,wdt));
65 flw = 1./b;
66 fup = 1.-wdt;
67 frn = flw+fup;
68 }
69
71
72 double z,prel,val;
73 while(1){
74 z = rnd->RndHadro().Rndm();
75 prel = 1.;
76 if (closeto0) {
77 if ( frn*rnd->RndHadro().Rndm()<flw ) z = wdt*z;
78 else { z = pow(wdt,z); prel = wdt/z; }
79 } else if (closeto1) {
80 if ( frn*rnd->RndHadro().Rndm()<flw) { z = wdt+log(z)/b; prel = exp(b*(z-wdt)); }
81 else z = wdt+(1.-wdt)*z;
82 }
83 if ( z>0 && z<1 ) {
84 double pw = b*(1./zpeak-1./z)+ log(zpeak/z) + a*log((1.-z)/(1.-zpeak));
85 val = exp(TMath::Max(-50.,TMath::Min(50.,pw)));
86 }
87 else val = 0.;
88 if ( val >= rnd->RndHadro().Rndm() * prel) break;
89 }
90
91 return z;
92}
93
94
95//____________________________________________________________________________
97EventRecordVisitorI("genie::LeptoHadPythia8")
98{
99 this->Initialize();
100}
101//____________________________________________________________________________
103EventRecordVisitorI("genie::LeptoHadPythia8", config)
104{
105 this->Initialize();
106}
107//____________________________________________________________________________
112//____________________________________________________________________________
114{
115
116 if(!this->Hadronize(event)) {
117 LOG("LeptoHad", pWARN) << "Hadronization failed!";
118 event->EventFlags()->SetBitNumber(kHadroSysGenErr, true);
120 exception.SetReason("Could not simulate the hadronic system");
121 exception.SwitchOnFastForward();
122 throw exception;
123 return;
124 }
125
126}
127//___________________________________________________________________________
129#ifdef __GENIE_PYTHIA8_ENABLED__
130 event // avoid unused variable warning if PYTHIA8 is not enabled
131#endif
132) const
133{
134
135#ifdef __GENIE_PYTHIA8_ENABLED__
136 // Compute kinematics of hadronic system with energy/momentum conservation
137 LongLorentzVector p4v( * event->Probe()->P4() );
138 LongLorentzVector p4N( * event->HitNucleon()->P4() );
139 LongLorentzVector p4l( * event->FinalStatePrimaryLepton()->P4() );
140 LongLorentzVector p4Hadlong( p4v.Px()+p4N.Px()-p4l.Px(), p4v.Py()+p4N.Py()-p4l.Py(), p4v.Pz()+p4N.Pz()-p4l.Pz(), p4v.E()+p4N.E()-p4l.E() );
141
142 LOG("LeptoHad", pDEBUG) << "v [LAB']: " << p4v.E() << " // " << p4v.M2() << " // [ " << p4v.Dx() << " , " << p4v.Dy() << " , " << p4v.Dz() << " ]";
143 LOG("LeptoHad", pDEBUG) << "N [LAB']: " << p4N.E() << " // " << p4N.M2() << " // [ " << p4N.Dx() << " , " << p4N.Dy() << " , " << p4N.Dz() << " ]";
144 LOG("LeptoHad", pDEBUG) << "l [LAB']: " << p4l.E() << " // " << p4l.M2() << " // [ " << p4l.Dx() << " , " << p4l.Dy() << " , " << p4l.Dz() << " ]";
145 LOG("LeptoHad", pDEBUG) << "H [LAB']: " << p4Hadlong.E() << " // " << p4Hadlong.M2() << " // [ " << p4Hadlong.Dx() << " , " << p4Hadlong.Dy() << " , " << p4Hadlong.Dz() << " ]";
146
147 // Translate from long double to double
148 const TLorentzVector & vtx = *( event->Probe()->X4());
149 TLorentzVector p4Had( (double)p4Hadlong.Px(), (double)p4Hadlong.Py(), (double)p4Hadlong.Pz(), (double)p4Hadlong.E() );
150 event->AddParticle(kPdgHadronicSyst, kIStDISPreFragmHadronicState, event->HitNucleonPosition(),-1,-1,-1, p4Had, vtx);
151
152 const Interaction * interaction = event->Summary();
153 interaction->KinePtr()->SetHadSystP4(p4Had);
154 interaction->KinePtr()->SetW(p4Hadlong.M());
155
156 double W = interaction->Kine().W();
157 if(W < fWmin) {
158 LOG("LeptoHad", pWARN) << "Low invariant mass, W = " << W << " GeV!!";
159 return false;
160 }
161
162 const XclsTag & xclstag = interaction->ExclTag();
163 const Target & target = interaction->InitState().Tgt();
164
165 assert(target.HitQrkIsSet());
166
167 bool isp = pdg::IsProton(target.HitNucPdg());
168 int hit_quark = target.HitQrkPdg();
169 int frag_quark = xclstag.FinalQuarkPdg();
170
171 LOG("LeptoHad", pDEBUG) << "Hit nucleon pdgc = " << target.HitNucPdg() << ", W = " << W;
172 LOG("LeptoHad", pDEBUG) << "Selected hit quark pdgc = " << hit_quark << " // Fragmentation quark = " << frag_quark;
173
175
176 //
177 // Generate the hadron combination to input PYTHIA
178 //
179 fPythia->event.reset();
180
181 //If the hit quark is a d we have these options:
182 /* uud(->q) => uu + q */
183 /* uud d(->q)db => uu + q (d valence and db sea annihilates)*/
184 /* udd(->q) => ud + q */
185 /* udd d(->q)db => ud + q (d valence and db sea annihilates)*/
186 if ( pdg::IsDQuark(hit_quark) ) {
187 // choose diquark system depending on proton or neutron
188 int diquark = 0;
189 if (isp) diquark = kPdgUUDiquarkS1;
190 else diquark = rnd->RndHadro().Rndm()>0.75 ? kPdgUDDiquarkS1 : kPdgUDDiquarkS0;
191 // Check that the trasnferred energy is higher than the mass of the produced quarks
192 double m_frag = PDGLibrary::Instance()->Find(frag_quark)->Mass();
193 double m_diquark = PDGLibrary::Instance()->Find(diquark)->Mass();
194 if( W <= m_frag + m_diquark + fMinESinglet ) {
195 LOG("LeptoHad", pWARN) << "Low invariant mass, W = " << W << " GeV! Returning a null list";
196 LOG("LeptoHad", pWARN) << "frag_quark = " << frag_quark << " -> m = " << m_frag;
197 LOG("LeptoHad", pWARN) << "diquark = " << diquark << " -> m = " << m_diquark;
198 return 0;
199 }
200 // Input the two particles to PYTHIA back to back in the CM frame
201 double e_frag = (W*W - m_diquark*m_diquark + m_frag*m_frag)/2./W;
202 double e_diquark = (W*W + m_diquark*m_diquark - m_frag*m_frag)/2./W;
203 double pz_cm = Pythia8::sqrtpos( e_frag*e_frag - m_frag*m_frag );
204 fPythia->event.append(frag_quark, 23, 101, 0, 0., 0., pz_cm, e_frag, m_frag);
205 fPythia->event.append(diquark, 23, 0, 101, 0., 0., -pz_cm, e_diquark, m_diquark);
206 }
207
208 //If the hit quark is a u we have these options:
209 /* u(->q)ud => ud + q */
210 /* uud u(->q)ub => ud + q (u valence and ub sea annihilates)*/
211 /* u(->q)dd => dd + q */
212 /* udd u(->q)ub => dd + q (u valence and ub sea annihilates)*/
213 else if ( pdg::IsUQuark(hit_quark) ) {
214 // choose diquark system depending on proton or neutron
215 int diquark = 0;
216 if (isp) diquark = rnd->RndHadro().Rndm()>0.75 ? kPdgUDDiquarkS1 : kPdgUDDiquarkS0;
217 else diquark = kPdgDDDiquarkS1;
218 // Check that the trasnferred energy is higher than the mass of the produced quarks.
219 double m_frag = PDGLibrary::Instance()->Find(frag_quark)->Mass();
220 double m_diquark = PDGLibrary::Instance()->Find(diquark)->Mass();
221 if( W <= m_frag + m_diquark + fMinESinglet ) {
222 LOG("LeptoHad", pWARN) << "Low invariant mass, W = " << W << " GeV! Returning a null list";
223 LOG("LeptoHad", pWARN) << "frag_quark = " << frag_quark << " -> m = " << m_frag;
224 LOG("LeptoHad", pWARN) << "diquark = " << diquark << " -> m = " << m_diquark;
225 return 0;
226 }
227 // Input the two particles to PYTHIA back to back in the CM frame
228 double e_frag = (W*W - m_diquark*m_diquark + m_frag*m_frag)/2./W;
229 double e_diquark = (W*W + m_diquark*m_diquark - m_frag*m_frag)/2./W;
230 double pz_cm = Pythia8::sqrtpos( e_frag*e_frag - m_frag*m_frag );
231 fPythia->event.append(frag_quark, 23, 101, 0, 0., 0., pz_cm, e_frag, m_frag);
232 fPythia->event.append(diquark, 23, 0, 101, 0., 0., -pz_cm, e_diquark, m_diquark);
233 }
234
235
236 // If the hit quark is not u or d then is more complicated.
237 // We are using the same procedure use in LEPTO (see lqev.F)
238 // Our initial systemt will look like this -> qqq + hit_q(->frag_q) + rema_q
239 // And we have to input PYTHIA something like this -> frag_q + rema + hadron
240 // These are the posible combinations -> frag_q[q] + meson [qqb] + diquark [qq]
241 // -> frag_q[qb] + baryon [qqq] + quark [q]
242 else {
243
244 // Remnant of the hit quark (which is from the sea) will be of opposite charge
245 int rema_hit_quark = -hit_quark;
246
247 // Check that the trasnfered energy is higher than the mass of the produce quarks plus remnant quark and nucleon
248 double m_frag = PDGLibrary::Instance()->Find(frag_quark)->Mass();
249 double m_rema_hit = PDGLibrary::Instance()->Find(rema_hit_quark)->Mass();
250 if (W <= m_frag + m_rema_hit + 0.9 + fMinESinglet ) {
251 LOG("LeptoHad", pWARN) << "Low invariant mass, W = " << W << " GeV! Returning a null list";
252 LOG("LeptoHad", pWARN) << " frag_quark = " << frag_quark << " -> m = " << m_frag;
253 LOG("LeptoHad", pWARN) << " rema_hit_quark = " << rema_hit_quark << " -> m = " << m_rema_hit;
254 return 0;
255 }
256
257 //PDG of the two hadronic particles for the final state
258 int hadron = 0;
259 int rema = 0;
260
261 int ntwoq = isp ? 2 : 1; //proton two ups & neutron one up
262 int counter = 0;
263
264 // Here we select the id and kinematics of the hadron and rema particles
265 // Some combinations can be kinematically forbiden so we repeat this process
266 // up to 100 times before the event is discarded.
267 while( counter<fMaxIterHad ) {
268
269 // Loop to create a combination of hadron + rema. Two options are possible:
270 // 1) diquark [qq] + meson [qqb]
271 // 2) quark [q] + baryon [qqq]
272 while(hadron==0) {
273 //choose a valence quark and the remaining will be a diquark system
274 int valquark = int(1.+ntwoq/3.+rnd->RndHadro().Rndm());
275 int diquark = 0;
276 if ( valquark==ntwoq ) diquark = rnd->RndHadro().Rndm()>0.75 ? kPdgUDDiquarkS1 : kPdgUDDiquarkS0;
277 else diquark = 1000*ntwoq+100*ntwoq+3;
278
279 // Choose flavours using PYTHIA tool
280 if ( rema_hit_quark>0 ) { //create a baryon (qqq)
281 hadron = getBaryon(diquark,rema_hit_quark,rnd->RndHadro().Rndm());
282 rema = valquark;
283 }
284 else { //create a meson (qqbar)
285 hadron = getMeson(valquark,rema_hit_quark,rnd->RndHadro().Rndm());
286 rema = diquark;
287 }
288 }
289
290 double m_hadron = PDGLibrary::Instance()->Find(hadron)->Mass();
291 double m_rema = PDGLibrary::Instance()->Find(rema)->Mass();
292
293 // Give balancing pT to hadron and rema particles
294 double pT = fRemnantPT * TMath::Sqrt( -1*TMath::Log( rnd->RndHadro().Rndm() ) );
295 double pT2 = TMath::Power(pT,2);
296 double pr = TMath::Power(m_hadron,2)+pT2;
297 //to generate the longitudinal scaling variable z in jet fragmentation using PYTHIA function
298 // Split energy-momentum of remnant using PYTHIA function
299 // z=E-pz fraction for rema forming jet-system with frag_q
300 // 1-z=E-pz fraction for hadron
301 double z = getRandomZ(Afrag,Bfrag*pr);
302
303 // Energy of trasnfered to the hadron
304 double tm_hadron = pr / z / W;
305 double E_hadron = 0.5 * ( z*W + tm_hadron ); //E_hadron - pz = zW
306 double E_pz = W - tm_hadron;
307 double WT = (1-z) * W * E_pz - pT2;
308
309 // Check if energy in jet system is enough for fragmentation.
310 if ( WT > TMath::Power(m_frag+m_rema+fMinESinglet,2) ) {
311
312 // Energy of transfered to the fragmented quark and rema system
313 // Applying energy conservation
314 WT = TMath::Sqrt( WT + pT2 );
315 double tm_rema = TMath::Power(m_rema,2) + pT2;
316 double E_frag = 0.5 * ( WT + ( TMath::Power(m_frag,2) - tm_rema)/WT ); //E_frag + E_rema = WT
317 double E_rema = 0.5 * ( WT + (-TMath::Power(m_frag,2) + tm_rema)/WT );
318 double x_rema = -1 * TMath::Sqrt( TMath::Power(E_rema,2) - tm_rema );
319 double theta_rema;
320 theta_rema = TMath::ATan2(pT,x_rema);
321
322 // Select a phi angle between between particles randomly
323 double phi = 2*kPi*rnd->RndHadro().Rndm();
324
325 double dbez = (E_pz-(1-z)*W)/(E_pz+(1-z)*W);
326 double pz_hadron = -0.5 * ( z*W - tm_hadron );
327
328 // Input the three particles to PYTHIA in the CM frame
329 // If a top quark is produced we decay it because it does not hadronize
330 fPythia->event.append(frag_quark, 23, 101, 0, 0., 0., sqrt(E_frag*E_frag-m_frag*m_frag), E_frag, m_frag);
331
332 double p_rema = sqrt(E_rema*E_rema-m_rema*m_rema);
333 fPythia->event.append(rema, 23, 0, 101, p_rema*sin(theta_rema)*sin(phi), p_rema*sin(theta_rema)*cos(phi), p_rema*cos(theta_rema), E_rema, m_rema);
334
335 fPythia->event.bst(0,0,dbez);
336
337 double theta_hadron = TMath::ATan2(pT,pz_hadron);
338
339 double p_hadron = sqrt(E_hadron*E_hadron-m_hadron*m_hadron);
340 fPythia->event.append(hadron, 23, 0, 0, p_hadron*sin(theta_hadron)*sin(phi+kPi), p_hadron*sin(theta_hadron)*cos(phi+kPi), p_hadron*cos(theta_hadron), E_hadron, m_hadron);
341
342 // Target remnants required to go backwards in hadronic cms
343 int nsize = fPythia->event.size();
344 if ( fPythia->event[nsize-1].pz()<0 && fPythia->event[nsize-2].pz()<0 ) break; //quit the while( counter<fMaxIterHad )
345
346 // break;
347
348 LOG("LeptoHad", pINFO) << "Not backward hadron or rema";
349 LOG("LeptoHad", pINFO) << "hadron = " << hadron << " -> Pz = " << fPythia->event[nsize-1].pz() ;
350 LOG("LeptoHad", pINFO) << "rema = " << rema << " -> Pz = " << fPythia->event[nsize-2].pz() ;
351 fPythia->event.reset();
352
353 }
354 else {
355 LOG("LeptoHad", pINFO) << "Low WT value ... ";
356 LOG("LeptoHad", pINFO) << "WT = " << TMath::Sqrt(WT) << " // m_frag = " << m_frag << " // m_rema = " << m_rema;
357 }
358
359 LOG("LeptoHad", pINFO) << "Hadronization paricles not suitable. Trying again... " << counter;
360 counter++;
361 if (counter==100) {
362 LOG("LeptoHad", pWARN) << "Hadronization particles failed after " << counter << " iterations! Returning a null list";
363 return 0;
364 }
365
366 }
367
368 }
369
370 // Introduce a primordial kT system
371 double pT = fPrimordialKT * TMath::Sqrt( -1*TMath::Log( rnd->RndHadro().Rndm() ) );
372 double phi = -2*kPi*rnd->RndHadro().Rndm();
373 double theta = 0.;
374
375 fPythia->event.rot(theta,phi);
376 phi = -1 * phi;
377 theta = TMath::ATan(2.*pT/W);
378 fPythia->event.rot(theta,phi);
379
380 // fPythia->event.list();
381 // fPythia->stat();
382
383 // Run PYTHIA with the input particles
384 fPythia->next();
385 // fPythia->event.list();
386 // fPythia->stat();
387 Pythia8::Event &fEvent = fPythia->event;
388 int np = fEvent.size();
389 assert(np>0);
390
391 // Boost velocity HCM -> LAB
392 long double beta = p4Hadlong.P()/p4Hadlong.E();
393
394 //fix numbering for events with top
395 bool isTop = false;
396
397 //-- Translate the fragmentation products from TMCParticles to
398 // GHepParticles and copy them to the event record.
399 int mom = event->FinalStateHadronicSystemPosition();
400 assert(mom!=-1);
401
402 for (int i = 1; i < np; i++) { // ignore first entry -> (system) pseudoparticle
403
404 int pdgc = fEvent[i].id();
405 if (!PDGLibrary::Instance()->Find(pdgc)) continue; // some intermediate particles not part of genie tables
406
407 int ks = fEvent[i].status();
408
409 // Final state particles can not be quarks or diquarks but colorless
410 if(ks > 0) {
411 if( pdg::IsQuark(pdgc) || pdg::IsDiQuark(pdgc) ) {
412 LOG("LeptoHad", pERROR) << "Hadronization failed! Bare quark/di-quarks appear in final state!";
413 return false;
414 }
415 }
416
417 // When top quark is produced, it is immidiately decay before hadronization. Then the decayed
418 // products are hadronized with the hadron remnants. Therefore, we remove the top quark from
419 // the list of particles so that the mother/daugher assigments is at the same level for decayed
420 // products and hadron remnants.
421 if ( pdg::IsTQuark( TMath::Abs(pdgc) ) ) { isTop=true; continue; }
422
423 // fix numbering scheme used for mother/daughter assignments
424 if ( isTop ) {
425 (fEvent[i].mother1()==0) ? fEvent[i].mothers(fEvent[i].mother1()-1,fEvent[i].mother2()) : fEvent[i].mothers(fEvent[i].mother1()-2,fEvent[i].mother2());
426 fEvent[i].daughters(fEvent[i].daughter1()-2,fEvent[i].daughter2()-2);
427 }
428 else {
429 fEvent[i].mothers(fEvent[i].mother1()-1,fEvent[i].mother2());
430 fEvent[i].daughters(fEvent[i].daughter1()-1,fEvent[i].daughter2()-1);
431 }
432
433 LongLorentzVector p4long( fEvent[i].px(), fEvent[i].py(), fEvent[i].pz(), fEvent[i].e() );
434 p4long.BoostZ(beta);
435 p4long.Rotate(p4Hadlong);
436
437 // Translate from long double to double
438 TLorentzVector p4( (double)p4long.Px(), (double)p4long.Py(), (double)p4long.Pz(), (double)p4long.E() );
439
440 // Somtimes PYTHIA output particles with E smaller than its mass. This is wrong,
441 // so we assume that the are at rest.
442 double massPDG = PDGLibrary::Instance()->Find(pdgc)->Mass();
443 if ( ks>0 && p4.E()<massPDG ) {
444 LOG("LeptoHad", pINFO) << "Putting at rest one stable particle generated by PYTHIA because E < m";
445 LOG("LeptoHad", pINFO) << "PDG = " << pdgc << " // State = " << ks;
446 LOG("LeptoHad", pINFO) << "E = " << p4.E() << " // |p| = " << p4.P();
447 LOG("LeptoHad", pINFO) << "p = [ " << p4.Px() << " , " << p4.Py() << " , " << p4.Pz() << " ]";
448 LOG("LeptoHad", pINFO) << "m = " << p4.M() << " // mpdg = " << massPDG;
449 p4.SetXYZT(0,0,0,massPDG);
450 }
451
452 // copy final state particles to the event record
454
455 int im = mom + 1 + fEvent[i].mother1();
456 int ifc = (fEvent[i].daughter1() <= -1) ? -1 : mom + 1 + fEvent[i].daughter1();
457 int ilc = (fEvent[i].daughter2() <= -1) ? -1 : mom + 1 + fEvent[i].daughter2();
458
459 double vx = vtx.X() + fEvent[i].xProd()*1e12; //pythia gives position in [mm] while genie uses [fm]
460 double vy = vtx.Y() + fEvent[i].yProd()*1e12;
461 double vz = vtx.Z() + fEvent[i].zProd()*1e12;
462 double vt = vtx.T() + fEvent[i].tProd()*(units::millimeter/units::second);
463 TLorentzVector pos( vx, vy, vz, vt );
464
465 event->AddParticle( pdgc, ist, im,-1, ifc, ilc, p4, pos );
466
467 }
468
469 return true;
470#else
471 return false;
472#endif
473
474}
475//____________________________________________________________________________
481//____________________________________________________________________________
487//____________________________________________________________________________
489{
490
491#ifdef __GENIE_PYTHIA8_ENABLED__
492 GetParam("MaxIter-Had", fMaxIterHad ) ;
493
494 // Width of Gaussian distribution for transverse momentums
495 // Define in LEPTO with PARL(3) and PARL(14)
496 GetParam("Primordial-kT", fPrimordialKT ) ;
497 GetParam("Remnant-pT", fRemnantPT ) ;
498
499 // It is, with quark masses added, used to define the minimum allowable energy of a colour-singlet parton system.
500 GetParam( "Energy-Singlet", fMinESinglet ) ;
501
502 GetParam( "Xsec-Wmin", fWmin ) ;
503
504 GetParam( "SSBarSuppression", fSSBarSuppression );
505 GetParam( "GaussianPt2", fGaussianPt2 );
506 GetParam( "NonGaussianPt2Tail", fNonGaussianPt2Tail );
507 GetParam( "RemainingEnergyCutoff", fRemainingECutoff );
508 GetParam( "DiQuarkSuppression", fDiQuarkSuppression );
509 GetParam( "LightVMesonSuppression", fLightVMesonSuppression );
510 GetParam( "SVMesonSuppression", fSVMesonSuppression );
511 GetParam( "Lunda", fLunda );
512 GetParam( "Lundb", fLundb );
513 GetParam( "LundaDiq", fLundaDiq );
514
515 fPythia->settings.parm("StringFlav:probStoUD", fSSBarSuppression);
516 fPythia->settings.parm("Diffraction:primKTwidth", fGaussianPt2);
517 fPythia->settings.parm("StringPT:enhancedFraction", fNonGaussianPt2Tail);
518 fPythia->settings.parm("StringFragmentation:stopMass", fRemainingECutoff);
519 fPythia->settings.parm("StringFlav:probQQtoQ", fDiQuarkSuppression);
520 fPythia->settings.parm("StringFlav:mesonUDvector", fLightVMesonSuppression);
521 fPythia->settings.parm("StringFlav:mesonSvector", fSVMesonSuppression);
522 fPythia->settings.parm("StringZ:aLund", fLunda);
523 fPythia->settings.parm("StringZ:bLund", fLundb);
524 fPythia->settings.parm("StringZ:aExtraDiquark", fLundaDiq);
525
526 // Same default mass of the W boson in pythia8 and genie, so no need to change in pythia8
527 // No problem with energy conservation W and top decays, so no need to set the width to 0
528
529 Afrag = fPythia->settings.parm("StringZ:aLund");
530 Bfrag = fPythia->settings.parm("StringZ:bLund");
531
532 bool isAvalid = true;
533 if (Afrag<0.02 || abs(Afrag-1)==0.01 ) isAvalid = false;
534 if (!isAvalid) {
535 LOG("LeptoHad", pFATAL) << "Invalid A factor for fragmenation function" ;
536 LOG("LeptoHad", pFATAL) << "A must be (>0.02 & <0.99) | >1.01" ;
537 exit(1);
538 }
539
540 mesonRateSum[0] = 1. + fPythia->settings.parm("StringFlav:mesonSvector"); //0.55
541 mesonRateSum[1] = 1. + fPythia->settings.parm("StringFlav:mesonCvector"); //0.88
542 mesonRateSum[2] = 1. + fPythia->settings.parm("StringFlav:mesonBvector"); //2.20
543
544 double decupletSup = fPythia->settings.parm("StringFlav:decupletSup");;
545 for (int i = 0; i < 6; ++i) CGSum[i] = CGOct[i] + decupletSup*CGDec[i];
546
547 LOG("LeptoHad", pINFO) << "Initialising PYTHIA..." ;
548 fPythia->init();
549#endif
550
551}
552//____________________________________________________________________________
554{
555
556#ifdef __GENIE_PYTHIA8_ENABLED__
557 fPythia = Pythia8Singleton::Instance()->Pythia8();
558
559 fPythia->readString("Print:quiet = on");
560
561 // sync GENIE and PYTHIA8 seeds
563 long int seed = rnd->GetSeed();
564 fPythia->readString("Random:setSeed = on");
565 fPythia->settings.mode("Random:seed", seed);
566 LOG("LeptoHad", pINFO) << "PYTHIA8 seed = " << fPythia->settings.mode("Random:seed");
567
568 //needed to only do hadronization
569 fPythia->readString("ProcessLevel:all = off");
570#endif
571
572}
573
#define pINFO
Definition Messenger.h:62
#define pERROR
Definition Messenger.h:59
#define pFATAL
Definition Messenger.h:56
#define pDEBUG
Definition Messenger.h:63
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
#define pWARN
Definition Messenger.h:60
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
virtual void Configure(const Registry &config)
Definition Algorithm.cxx:62
GENIE's GHEP MC event record.
Definition GHepRecord.h:45
const Target & Tgt(void) const
Summary information for an interaction.
Definition Interaction.h:56
const XclsTag & ExclTag(void) const
Definition Interaction.h:72
const Kinematics & Kine(void) const
Definition Interaction.h:71
const InitialState & InitState(void) const
Definition Interaction.h:69
Kinematics * KinePtr(void) const
Definition Interaction.h:76
void SetHadSystP4(const TLorentzVector &p4)
double W(bool selected=false) const
void SetW(double W, bool selected=false)
double mesonRateSum[3]
meson parameter
void Configure(const Registry &config)
double fSSBarSuppression
ssbar suppression
double fNonGaussianPt2Tail
non gaussian pt2 tail parameterization
double fLundaDiq
adjustment of Lund a for di-quark
double fLunda
Lund a parameter.
int getBaryon(int, int, double) const
create baryon
double getRandomZ(double, double) const
fragmentation
double CGOct[6]
baryon parameter
double CGDec[6]
baryon parameter
void ProcessEventRecord(GHepRecord *event) const
int getMeson(int, int, double) const
create meson
double fGaussianPt2
gaussian pt2 distribution width
double Bfrag
fragmentation parameter
double fDiQuarkSuppression
di-quark suppression parameter
double fLightVMesonSuppression
light vector meson suppression
double fRemainingECutoff
remaining E cutoff stopping fragmentation
void Initialize(void) const
double CGSum[6]
baryon parameter
bool Hadronize(GHepRecord *event) const
double fSVMesonSuppression
strange vector meson suppression
double Afrag
fragmentation parameter
double fLundb
Lund b parameter.
static PDGLibrary * Instance(void)
TParticlePDG * Find(int pdgc, bool must_exist=true)
static Pythia8Singleton * Instance(void)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition RandomGen.h:29
TRandom3 & RndHadro(void) const
rnd number generator used by hadronization models
Definition RandomGen.h:53
static RandomGen * Instance()
Access instance.
Definition RandomGen.cxx:74
long int GetSeed(void) const
Definition RandomGen.h:82
A registry. Provides the container for algorithm configuration parameters.
Definition Registry.h:65
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition Target.h:40
int HitNucPdg(void) const
Definition Target.cxx:304
int HitQrkPdg(void) const
Definition Target.cxx:242
bool HitQrkIsSet(void) const
Definition Target.cxx:292
Contains minimal information for tagging exclusive processes.
Definition XclsTag.h:39
int FinalQuarkPdg(void) const
Definition XclsTag.h:72
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
void Rotate(LongLorentzVector axis)
Definition MathUtils.h:68
const double e
const double a
bool IsQuark(int pdgc)
Definition PDGUtils.cxx:250
bool IsProton(int pdgc)
Definition PDGUtils.cxx:336
bool IsTQuark(int pdgc)
Definition PDGUtils.cxx:291
bool IsUQuark(int pdgc)
Definition PDGUtils.cxx:266
bool IsDQuark(int pdgc)
Definition PDGUtils.cxx:271
bool IsDiQuark(int pdgc)
Definition PDGUtils.cxx:231
static constexpr double millimeter
Definition Units.h:41
static constexpr double second
Definition Units.h:37
Simple functions for loading and reading nucleus dependent keys from config files.
@ kIStDISPreFragmHadronicState
Definition GHepStatus.h:35
@ kIStStableFinalState
Definition GHepStatus.h:30
const int kPdgUDDiquarkS0
Definition PDGCodes.h:56
const int kPdgUUDiquarkS1
Definition PDGCodes.h:58
const int kPdgHadronicSyst
Definition PDGCodes.h:210
enum genie::EGHepStatus GHepStatus_t
const int kPdgUDDiquarkS1
Definition PDGCodes.h:57
const int kPdgDDDiquarkS1
Definition PDGCodes.h:55
@ kHadroSysGenErr
Definition GHepFlags.h:32