12 #include <TClonesArray.h>
17 #include "Framework/Conventions/GBuild.h"
30 #ifdef __GENIE_PYTHIA6_ENABLED__
31 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,6)
32 #include <TMCParticle.h>
34 #include <TMCParticle6.h>
36 #endif // __GENIE_PYTHIA6_ENABLED__
38 using namespace genie;
39 using namespace genie::constants;
43 double pyangl_(
double *,
double * );
44 void pykfdi_(
int *,
int *,
int *,
int * );
45 void pyzdis_(
int *,
int *,
double *,
double * );
46 void pyrobo_(
int *,
int *,
double *,
double *,
double *,
double *,
double * );
48 void py2ent_(
int *,
int *,
int *,
double * );
71 #ifdef __GENIE_PYTHIA6_ENABLED__
86 #ifdef __GENIE_PYTHIA6_ENABLED__
89 LOG(
"LeptoHad",
pWARN) <<
"Hadronization failed!";
92 exception.
SetReason(
"Could not simulate the hadronic system");
100 <<
"Calling GENIE/PYTHIA6 without enabling PYTHIA6";
114 #ifdef __GENIE_PYTHIA6_ENABLED__
119 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() );
121 LOG(
"LeptoHad",
pDEBUG) <<
"v [LAB']: " << p4v.E() <<
" // " << p4v.M2() <<
" // [ " << p4v.Dx() <<
" , " << p4v.Dy() <<
" , " << p4v.Dz() <<
" ]";
122 LOG(
"LeptoHad",
pDEBUG) <<
"N [LAB']: " << p4N.E() <<
" // " << p4N.M2() <<
" // [ " << p4N.Dx() <<
" , " << p4N.Dy() <<
" , " << p4N.Dz() <<
" ]";
123 LOG(
"LeptoHad",
pDEBUG) <<
"l [LAB']: " << p4l.E() <<
" // " << p4l.M2() <<
" // [ " << p4l.Dx() <<
" , " << p4l.Dy() <<
" , " << p4l.Dz() <<
" ]";
124 LOG(
"LeptoHad",
pDEBUG) <<
"H [LAB']: " << p4Hadlong.E() <<
" // " << p4Hadlong.M2() <<
" // [ " << p4Hadlong.Dx() <<
" , " << p4Hadlong.Dy() <<
" , " << p4Hadlong.Dz() <<
" ]";
127 const TLorentzVector & vtx = *(
event->Probe()->X4());
128 TLorentzVector p4Had( (
double)p4Hadlong.Px(), (double)p4Hadlong.Py(), (double)p4Hadlong.Pz(), (double)p4Hadlong.E() );
131 const Interaction * interaction =
event->Summary();
135 double W = interaction->
Kine().
W();
137 LOG(
"LeptoHad",
pWARN) <<
"Low invariant mass, W = " << W <<
" GeV!!";
151 LOG(
"LeptoHad",
pDEBUG) <<
"Selected hit quark pdgc = " << hit_quark <<
" // Fragmentation quark = " << frag_quark;
159 double pmas1_W =
fPythia->GetPMAS(24,1);
160 double pmas2_W =
fPythia->GetPMAS(24,2);
161 double pmas2_t =
fPythia->GetPMAS(6,2);
180 LOG(
"LeptoHad",
pWARN) <<
"Low invariant mass, W = " << W <<
" GeV! Returning a null list";
181 LOG(
"LeptoHad",
pWARN) <<
"frag_quark = " << frag_quark <<
" -> m = " << m_frag;
182 LOG(
"LeptoHad",
pWARN) <<
"diquark = " << diquark <<
" -> m = " << m_diquark;
187 fPythia->Py1ent( -1, frag_quark, (W*W - m_diquark*m_diquark + m_frag*m_frag)/2./W, 0., 0. );
192 fPythia->Py1ent(
fPythia->GetN()+1, diquark, (W*W + m_diquark*m_diquark - m_frag*m_frag)/2./W,
fPythia->GetPARU(1), 0. );
209 LOG(
"LeptoHad",
pWARN) <<
"Low invariant mass, W = " << W <<
" GeV! Returning a null list";
210 LOG(
"LeptoHad",
pWARN) <<
"frag_quark = " << frag_quark <<
" -> m = " << m_frag;
211 LOG(
"LeptoHad",
pWARN) <<
"diquark = " << diquark <<
" -> m = " << m_diquark;
215 fPythia->Py1ent( -1, frag_quark, (W*W - m_diquark*m_diquark + m_frag*m_frag)/2./W, 0., 0. );
216 fPythia->Py1ent(
fPythia->GetN()+1, diquark, (W*W + m_diquark*m_diquark - m_frag*m_frag)/2./W,
fPythia->GetPARU(1), 0. );
228 int rema_hit_quark = -hit_quark;
234 LOG(
"LeptoHad",
pWARN) <<
"Low invariant mass, W = " << W <<
" GeV! Returning a null list";
235 LOG(
"LeptoHad",
pWARN) <<
" frag_quark = " << frag_quark <<
" -> m = " << m_frag;
236 LOG(
"LeptoHad",
pWARN) <<
" rema_hit_quark = " << rema_hit_quark <<
" -> m = " << m_rema_hit;
244 int ntwoq = isp ? 2 : 1;
257 int valquark = int(1.+ntwoq/3.+rnd->
RndHadro().Rndm());
260 else diquark = 1000*ntwoq+100*ntwoq+3;
264 if ( rema_hit_quark>0 ) {
265 pykfdi_(&diquark,&rema_hit_quark,&idum,&hadron);
269 pykfdi_(&valquark,&rema_hit_quark,&idum,&hadron);
279 double pT2 = TMath::Power(pT,2);
280 double pr = TMath::Power(m_hadron,2)+pT2;
291 double tm_hadron = pr / z /
W;
292 double E_hadron = 0.5 * ( z*W + tm_hadron );
293 double E_pz = W - tm_hadron;
294 double WT = (1-z) * W * E_pz - pT2;
297 if ( WT > TMath::Power(m_frag+m_rema+
fMinESinglet,2) ) {
301 WT = TMath::Sqrt( WT + pT2 );
302 double tm_rema = TMath::Power(m_rema,2) + pT2;
303 double E_frag = 0.5 * ( WT + ( TMath::Power(m_frag,2) - tm_rema)/WT );
304 double E_rema = 0.5 * ( WT + (-TMath::Power(m_frag,2) + tm_rema)/WT );
305 double x_rema = -1 * TMath::Sqrt( TMath::Power(E_rema,2) - tm_rema );
306 double theta_rema =
pyangl_(&x_rema,&pT);
313 fPythia->Py1ent( -1, frag_quark, E_frag, 0., 0. );
314 if (TMath::Abs(frag_quark) > 5 ) {
318 fPythia->Py1ent(
fPythia->GetN()+1, rema, E_rema, theta_rema, phi );
322 double the = 0.;
double ph = 0.;
323 double dbex = 0.;
double dbey = 0.;
double dbez = (E_pz-(1-z)*W)/(E_pz+(1-z)*W);
324 pyrobo_( &imin , &imax, &the, &ph, &dbex, &dbey , &dbez );
326 double pz_hadron = -0.5 * ( z*W - tm_hadron );
327 double theta_hadron =
pyangl_(&pz_hadron,&pT);
336 LOG(
"LeptoHad",
pINFO) <<
"Not backward hadron or rema";
342 LOG(
"LeptoHad",
pINFO) <<
"Low WT value ... ";
343 LOG(
"LeptoHad",
pINFO) <<
"WT = " << TMath::Sqrt(WT) <<
" // m_frag = " << m_frag <<
" // m_rema = " << m_rema;
346 LOG(
"LeptoHad",
pINFO) <<
"Hadronization paricles not suitable. Trying again... " << counter;
349 LOG(
"LeptoHad",
pWARN) <<
"Hadronization particles failed after " << counter <<
" iterations! Returning a null list";
363 double dbex = 0.;
double dbey = 0.;
double dbez = 0;
364 pyrobo_( &imin , &imax, &theta, &phi, &dbex, &dbey , &dbez );
366 theta = TMath::ATan(2.*pT/W);
367 pyrobo_( &imin , &imax, &theta, &phi, &dbex, &dbey , &dbez );
373 fPythia->SetPMAS(24,1,pmas1_W);
374 fPythia->SetPMAS(24,2,pmas2_W);
382 TClonesArray * pythia_particles = (TClonesArray *)
fPythia->ImportParticles(
"All");
387 int np = pythia_particles->GetEntries();
389 TClonesArray * particle_list =
new TClonesArray(
"genie::GHepParticle", np);
390 particle_list->SetOwner(
true);
393 long double beta = p4Hadlong.P()/p4Hadlong.E();
400 int mom =
event->FinalStateHadronicSystemPosition();
404 TIter particle_iter(pythia_particles);
405 while( (p = (TMCParticle *) particle_iter.Next()) ) {
407 int pdgc = p->GetKF();
413 LOG(
"LeptoHad",
pERROR) <<
"Hadronization failed! Bare quark/di-quarks appear in final state!";
422 if (
pdg::IsTQuark( TMath::Abs(pdgc) ) ) { isTop=
true;
continue; }
426 (p->GetParent()==0) ? p->SetParent(p->GetParent() - 1) : p->SetParent(p->GetParent() - 2);
427 p->SetFirstChild (p->GetFirstChild() - 2);
428 p->SetLastChild (p->GetLastChild() - 2);
431 p->SetParent(p->GetParent() - 1);
432 p->SetFirstChild (p->GetFirstChild() - 1);
433 p->SetLastChild (p->GetLastChild() - 1);
438 p4long.Rotate(p4Hadlong);
441 TLorentzVector p4( (
double)p4long.Px(), (double)p4long.Py(), (double)p4long.Pz(), (double)p4long.E() );
446 if ( (ks==1 || ks==4) && p4.E() < massPDG ) {
447 LOG(
"LeptoHad",
pINFO) <<
"Putting at rest one stable particle generated by PYTHIA because E < m";
448 LOG(
"LeptoHad",
pINFO) <<
"PDG = " << pdgc <<
" // State = " << ks;
449 LOG(
"LeptoHad",
pINFO) <<
"E = " << p4.E() <<
" // |p| = " << p4.P();
450 LOG(
"LeptoHad",
pINFO) <<
"p = [ " << p4.Px() <<
" , " << p4.Py() <<
" , " << p4.Pz() <<
" ]";
451 LOG(
"LeptoHad",
pINFO) <<
"m = " << p4.M() <<
" // mpdg = " << massPDG;
452 p4.SetXYZT(0,0,0,massPDG);
458 int im = mom + 1 + p->GetParent();
459 int ifc = (p->GetFirstChild() <= -1) ? -1 : mom + 1 + p->GetFirstChild();
460 int ilc = (p->GetLastChild() <= -1) ? -1 : mom + 1 + p->GetLastChild();
462 double vx = vtx.X() + p->GetVx()*1e12;
463 double vy = vtx.Y() + p->GetVy()*1e12;
464 double vz = vtx.Z() + p->GetVz()*1e12;
466 TLorentzVector pos( vx, vy, vz, vt );
468 event->AddParticle( pdgc, ist, im,-1, ifc, ilc, p4, pos );
475 #endif // __GENIE_PYTHIA6_ENABLED__
505 #ifdef __GENIE_PYTHIA6_ENABLED__
510 int warnings;
GetParam(
"Warnings", warnings ) ;
511 int errors;
GetParam(
"Errors", errors ) ;
512 int qrk_mass;
GetParam(
"QuarkMass", qrk_mass ) ;
514 fPythia->SetMSTU(26, warnings);
516 fPythia->SetMSTJ(93, qrk_mass);
TPythia6 * fPythia
PYTHIA6 wrapper class.
void Configure(const Registry &config)
const int kPdgUUDiquarkS1
double W(bool selected=false) const
void pyrobo_(int *, int *, double *, double *, double *, double *, double *)
static RandomGen * Instance()
Access instance.
int HitNucPdg(void) const
#define __GENIE_PYTHIA6_ENABLED__
Kinematics * KinePtr(void) const
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the 'Visito...
int HitQrkPdg(void) const
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Contains minimal information for tagging exclusive processes.
double W(const Interaction *const i)
void ProcessEventRecord(GHepRecord *event) const
Summary information for an interaction.
static constexpr double millimeter
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
static constexpr double second
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
const int kPdgUDDiquarkS1
const Kinematics & Kine(void) const
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
virtual void Configure(const Registry &config)
void py2ent_(int *, int *, int *, double *)
virtual ~LeptoHadronization()
const int kPdgUDDiquarkS0
int FinalQuarkPdg(void) const
void pykfdi_(int *, int *, int *, int *)
TRandom3 & RndHadro(void) const
rnd number generator used by hadronization models
void SetW(double W, bool selected=false)
void SwitchOnFastForward(void)
static PDGLibrary * Instance(void)
void SetReason(string reason)
void Initialize(void) const
void BoostZ(long double bz)
bool HitQrkIsSet(void) const
A registry. Provides the container for algorithm configuration parameters.
const XclsTag & ExclTag(void) const
void SetHadSystP4(const TLorentzVector &p4)
const InitialState & InitState(void) const
void pyzdis_(int *, int *, double *, double *)
TParticlePDG * Find(int pdgc, bool must_exist=true)
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
const Target & Tgt(void) const
double pyangl_(double *, double *)
const int kPdgHadronicSyst
GENIE's GHEP MC event record.
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
bool Hadronize(GHepRecord *event) const
enum genie::EGHepStatus GHepStatus_t
const int kPdgDDDiquarkS1