Pythia6Hadronization.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2019, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5  or see $GENIE/LICENSE
6 
7  Author: Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
8  University of Liverpool & STFC Rutherford Appleton Lab
9 */
10 //____________________________________________________________________________
11 
12 #include <RVersion.h>
13 #include <TClonesArray.h>
14 
28 
29 #ifdef __GENIE_PYTHIA6_ENABLED__
30 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,6)
31 #include <TMCParticle.h>
32 #else
33 #include <TMCParticle6.h>
34 #endif
35 #endif // __GENIE_PYTHIA6_ENABLED__
36 
37 using namespace genie;
38 using namespace genie::constants;
39 
40 // the actual PYTHIA call
41 extern "C" void py2ent_(int *, int *, int *, double *);
42 
43 //____________________________________________________________________________
45 PythiaHadronizationBase("genie::Pythia6Hadronization")
46 {
47  this->Initialize();
48 }
49 //____________________________________________________________________________
51 PythiaHadronizationBase("genie::Pythia6Hadronization", config)
52 {
53  this->Initialize();
54 }
55 //____________________________________________________________________________
57 {
58 
59 }
60 //____________________________________________________________________________
63  event // avoid unused variable warning if PYTHIA6 is not enabled
64  #endif
65 ) const
66 {
67 #ifdef __GENIE_PYTHIA6_ENABLED__
69 #else
70  LOG("Pythia6Had", pFATAL)
71  << "Calling GENIE/PYTHIA6 hadronization modules without enabling PYTHIA6";
72  gAbortingInErr = true;
73  std::exit(1);
74 #endif
75 }
76 //____________________________________________________________________________
79  event // avoid unused variable warning if PYTHIA6 is not enabled
80 #endif
81 ) const
82 {
83 #ifdef __GENIE_PYTHIA6_ENABLED__
84 
85  LOG("Pythia6Had", pNOTICE) << "Running PYTHIA6 hadronizer";
86 
87  const Interaction * interaction = event->Summary();
88  const Kinematics & kinematics = interaction->Kine();
89  double W = kinematics.W();
90 
91  LOG("Pythia6Had", pNOTICE)
92  << "Fragmentation: "
93  << "q = " << fLeadingQuark << ", qq = " << fRemnantDiquark
94  << ", W = " << W;
95 
96  // Hadronize
97  int ip = 0;
98  py2ent_(&ip, &fLeadingQuark, &fRemnantDiquark, &W); // hadronizer
99 
100  // Get LUJETS record
101  fPythia->GetPrimaries();
102  TClonesArray * pythia_particles =
103  (TClonesArray *) fPythia->ImportParticles("All");
104 
105  // Copy PYTHIA container to a new TClonesArray so as to transfer ownership
106  // of the container and of its elements to the calling method
107 
108  int np = pythia_particles->GetEntries();
109  assert(np>0);
110  TClonesArray * particle_list = new TClonesArray("genie::GHepParticle", np);
111  particle_list->SetOwner(true);
112 
113  // Hadronic 4vec
114  TLorentzVector p4Had = kinematics.HadSystP4();
115 
116  // Vector defining rotation from LAB to LAB' (z:= \vec{phad})
117  TVector3 unitvq = p4Had.Vect().Unit();
118 
119  // Boost velocity LAB' -> HCM
120  TVector3 beta(0,0,p4Had.P()/p4Had.Energy());
121 
122  // Check target and decide appropriate status code for f/s particles
123  bool is_nucleus = interaction->InitState().Tgt().IsNucleus();
125 
126  // Get the index of the mother of the hadronic system
127  int mom = event->FinalStateHadronicSystemPosition();
128  assert(mom!=-1);
129 
130  // Get the neutrino vertex position (all hadrons positions set to this point)
131  GHepParticle * neutrino = event->Probe();
132  const TLorentzVector & vtx = *(neutrino->X4());
133 
134  // Loop over PYTHIA8 event particles and copy relevant entries
135  unsigned int i = 0;
136  TMCParticle * p = 0;
137  TIter particle_iter(pythia_particles);
138  while( (p = (TMCParticle *) particle_iter.Next()) ) {
139 
140  int particle_pdg_code = p->GetKF();
141  int pythia_particle_status = p->GetKS();
142 
143  // Sanity check
144  if(pythia_particle_status == 1) {
145  if( pdg::IsQuark (particle_pdg_code) ||
146  pdg::IsDiQuark(particle_pdg_code) )
147  {
148  LOG("Pythia6Had", pERROR)
149  << "Hadronization failed! Bare quarks appear in final state!";
150  return false;
151  }
152  }
153 
154  // The fragmentation products are generated in the hadronic CM frame
155  // where the z>0 axis is the \vec{phad} direction. For each particle
156  // returned by the hadronizer:
157  // - boost it back to LAB' frame {z:=\vec{phad}} / doesn't affect pT
158  // - rotate its 3-momentum from LAB' to LAB
159  TLorentzVector p4o(p->GetPx(), p->GetPy(), p->GetPz(), p->GetEnergy());
160  p4o.Boost(beta);
161  TVector3 p3 = p4o.Vect();
162  p3.RotateUz(unitvq);
163  TLorentzVector p4(p3,p4o.Energy());
164 
165  // Set the proper GENIE status according to a number of things:
166  // interaction on a nucleus or nucleon, particle type
167  GHepStatus_t ist = (pythia_particle_status == 1) ?
169  // Handle gammas, and leptons that might come from internal pythia decays
170  // mark them as final state particles
171  bool is_gamma = (particle_pdg_code == kPdgGamma);
172  bool is_nu = pdg::IsNeutralLepton(particle_pdg_code);
173  bool is_lchg = pdg::IsChargedLepton(particle_pdg_code);
174  bool not_hadr = is_gamma || is_nu || is_lchg;
175  if(not_hadr) { ist = kIStStableFinalState; }
176 
177  // Set mother/daugher indices
178  int mother1 = mom + p->GetParent();
179  int mother2 = -1;
180  int daughter1 = (p->GetFirstChild() <= 0 ) ? -1 : mom + p->GetFirstChild();
181  int daughter2 = (p->GetLastChild() <= 0 ) ? -1 : mom + p->GetLastChild();
182 
183  // Create GHepParticle
184  GHepParticle particle = GHepParticle(
185  particle_pdg_code, // pdg
186  ist, // status
187  mother1, // first parent
188  mother2, // second parent
189  daughter1, // first daughter
190  daughter2, // second daughter
191  p4.Px(), // px
192  p4.Py(), // py
193  p4.Pz(), // pz
194  p4.Energy(), // e
195  vtx.X(), // x
196  vtx.Y(), // y
197  vtx.Z(), // z
198  vtx.T() // t
199  );
200 
201  LOG("Pythia6Had", pDEBUG)
202  << "Adding final state particle pdgc = " << particle.Pdg()
203  << " with status = " << particle.Status();
204 
205  // Insert the particle in the list
206  event->AddParticle(particle);
207  }
208  return true;
209 
210 #else
211  return false;
212 #endif // __GENIE_PYTHIA6_ENABLED__
213 }
214 //____________________________________________________________________________
216 {
217 #ifdef __GENIE_PYTHIA6_ENABLED__
218  fOriDecayFlag_pi0 = (fPythia->GetMDCY(fPythia->Pycomp(kPdgPi0), 1) == 1);
219  fOriDecayFlag_K0 = (fPythia->GetMDCY(fPythia->Pycomp(kPdgK0), 1) == 1);
220  fOriDecayFlag_K0b = (fPythia->GetMDCY(fPythia->Pycomp(kPdgAntiK0), 1) == 1);
221  fOriDecayFlag_L0 = (fPythia->GetMDCY(fPythia->Pycomp(kPdgLambda), 1) == 1);
222  fOriDecayFlag_L0b = (fPythia->GetMDCY(fPythia->Pycomp(kPdgAntiLambda), 1) == 1);
223  fOriDecayFlag_Dm = (fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaM), 1) == 1);
224  fOriDecayFlag_D0 = (fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_Delta0), 1) == 1);
225  fOriDecayFlag_Dp = (fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaP), 1) == 1);
226  fOriDecayFlag_Dpp = (fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaPP), 1) == 1);
227 
228 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
229  LOG("Pythia6Had", pDEBUG)
230  << "Original PYTHIA6 decay flags:"
231  << "\n pi0 = " << fOriDecayFlag_pi0
232  << "\n K0 = " << fOriDecayFlag_K0
233  << "\n \bar{K0} = " << fOriDecayFlag_K0b
234  << "\n Lambda = " << fOriDecayFlag_L0
235  << "\n \bar{Lambda0} = " << fOriDecayFlag_L0b
236  << "\n D- = " << fOriDecayFlag_Dm
237  << "\n D0 = " << fOriDecayFlag_D0
238  << "\n D+ = " << fOriDecayFlag_Dp
239  << "\n D++ = " << fOriDecayFlag_Dpp;
240 #endif
241 
242 #endif // __GENIE_PYTHIA6_ENABLED__
243 }
244 //____________________________________________________________________________
246 {
247 #ifdef __GENIE_PYTHIA6_ENABLED__
248 
249  fPythia->SetMDCY(fPythia->Pycomp(kPdgPi0),
250  1, (fReqDecayFlag_pi0) ? 1 : 0);
251  fPythia->SetMDCY(fPythia->Pycomp(kPdgK0),
252  1, (fReqDecayFlag_K0) ? 1 : 0);
253  fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiK0),
254  1, (fReqDecayFlag_K0b) ? 1 : 0);
255  fPythia->SetMDCY(fPythia->Pycomp(kPdgLambda),
256  1, (fReqDecayFlag_L0) ? 1 : 0);
257  fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiLambda),
258  1, (fReqDecayFlag_L0b) ? 1 : 0);
259  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaM),
260  1, (fReqDecayFlag_Dm) ? 1 : 0);
261  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_Delta0),
262  1, (fReqDecayFlag_D0) ? 1 : 0);
263  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaP),
264  1, (fReqDecayFlag_Dp) ? 1 : 0);
265  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaPP),
266  1, (fReqDecayFlag_Dpp) ? 1 : 0);
267 
268 #endif // __GENIE_PYTHIA6_ENABLED__
269 }
270 //____________________________________________________________________________
272 {
273 #ifdef __GENIE_PYTHIA6_ENABLED__
274 
275 fPythia->SetMDCY(fPythia->Pycomp(kPdgPi0),
276  1, (fOriDecayFlag_pi0) ? 1 : 0);
277 fPythia->SetMDCY(fPythia->Pycomp(kPdgK0),
278  1, (fOriDecayFlag_K0) ? 1 : 0);
279 fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiK0),
280  1, (fOriDecayFlag_K0b) ? 1 : 0);
281 fPythia->SetMDCY(fPythia->Pycomp(kPdgLambda),
282  1, (fOriDecayFlag_L0) ? 1 : 0);
283 fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiLambda),
284  1, (fOriDecayFlag_L0b) ? 1 : 0);
285 fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaM),
286  1, (fOriDecayFlag_Dm) ? 1 : 0);
287 fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_Delta0),
288  1, (fOriDecayFlag_D0) ? 1 : 0);
289 fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaP),
290  1, (fOriDecayFlag_Dp) ? 1 : 0);
291 fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaPP),
292  1, (fOriDecayFlag_Dpp) ? 1 : 0);
293 
294 #endif // __GENIE_PYTHIA6_ENABLED__
295 }
296 //____________________________________________________________________________
298 {
299  Algorithm::Configure(config);
300  this->LoadConfig();
301 }
302 //____________________________________________________________________________
304 {
305  Algorithm::Configure(config);
306  this->LoadConfig();
307 }
308 //____________________________________________________________________________
310 {
312 
313 #ifdef __GENIE_PYTHIA6_ENABLED__
314  fPythia->SetPARJ(2, fSSBarSuppression );
315  fPythia->SetPARJ(21, fGaussianPt2 );
316  fPythia->SetPARJ(23, fNonGaussianPt2Tail );
317  fPythia->SetPARJ(33, fRemainingECutoff );
318  fPythia->SetPARJ(1, fDiQuarkSuppression );
319  fPythia->SetPARJ(11, fLightVMesonSuppression );
320  fPythia->SetPARJ(12, fSVMesonSuppression );
321  fPythia->SetPARJ(41, fLunda );
322  fPythia->SetPARJ(42, fLundb );
323  fPythia->SetPARJ(45, fLundaDiq );
324 #endif
325 
326  LOG("Pythia6Had", pDEBUG) << this->GetConfig() ;
327 }
328 //____________________________________________________________________________
330 {
332 #ifdef __GENIE_PYTHIA6_ENABLED__
333  fPythia = TPythia6::Instance();
334  // sync GENIE/PYTHIA6 seed number
335  // PYTHIA6 is a singleton, so do this from RandomGen for all
336  // GENIE algorithms that use PYTHIA6
338 #endif
339 }
340 //____________________________________________________________________________
const int kPdgP33m1232_DeltaPP
Definition: PDGCodes.h:91
double W(bool selected=false) const
Definition: Kinematics.cxx:167
Basic constants.
double fGaussianPt2
gaussian pt2 distribution width
void Configure(const Registry &config)
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:26
#define pERROR
Definition: Messenger.h:60
const int kPdgLambda
Definition: PDGCodes.h:69
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
enum genie::EGHepStatus GHepStatus_t
#define pFATAL
Definition: Messenger.h:57
bool IsNucleus(void) const
Definition: Target.cxx:289
Generated/set kinematical variables for an event.
Definition: Kinematics.h:40
double fRemainingECutoff
remaining E cutoff stopping fragmentation
bool IsChargedLepton(int pdgc)
Definition: PDGUtils.cxx:99
const TLorentzVector & HadSystP4(void) const
Definition: Kinematics.h:67
double fDiQuarkSuppression
di-quark suppression parameter
double fLundaDiq
adjustment of Lund a for di-quark
GHepStatus_t Status(void) const
Definition: GHepParticle.h:65
virtual const Registry & GetConfig(void) const
Definition: Algorithm.cxx:255
const int kPdgP33m1232_DeltaP
Definition: PDGCodes.h:90
const int kPdgP33m1232_DeltaM
Definition: PDGCodes.h:88
#define __GENIE_PYTHIA6_ENABLED__
const int kPdgK0
Definition: PDGCodes.h:155
double fSVMesonSuppression
strange vector meson suppression
int Pdg(void) const
Definition: GHepParticle.h:64
bool Hadronize(GHepRecord *event) const
Summary information for an interaction.
Definition: Interaction.h:55
TPythia6 * fPythia
PYTHIA6 wrapper class.
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:97
void py2ent_(int *, int *, int *, double *)
static Config * config
Definition: config.cpp:1054
const int kPdgGamma
Definition: PDGCodes.h:170
bool IsDiQuark(int pdgc)
Definition: PDGUtils.cxx:229
const Kinematics & Kine(void) const
Definition: Interaction.h:70
virtual void Configure(const Registry &config)
Definition: Algorithm.cxx:71
const int kPdgPi0
Definition: PDGCodes.h:141
void ProcessEventRecord(GHepRecord *event) const
const int kPdgAntiK0
Definition: PDGCodes.h:156
Base class for the Pythia (6 and 8) hadronization modules in GENIE. In particular, the base class provides common checks and basic assignments of quark/diquark codes for a no frills interface to Pythia hadronization routines.
virtual void ProcessEventRecord(GHepRecord *event) const
const int kPdgP33m1232_Delta0
Definition: PDGCodes.h:89
bool IsNeutralLepton(int pdgc)
Definition: PDGUtils.cxx:93
p
Definition: test.py:223
const TLorentzVector * X4(void) const
Definition: GHepParticle.h:80
A registry. Provides the container for algorithm configuration parameters.
Definition: Registry.h:66
bool IsQuark(int pdgc)
Definition: PDGUtils.cxx:239
double fLightVMesonSuppression
light vector meson suppression
void RestoreOriginalDecayFlags(void) const
const InitialState & InitState(void) const
Definition: Interaction.h:68
#define pNOTICE
Definition: Messenger.h:62
double fNonGaussianPt2Tail
non gaussian pt2 tail parameterization
const Target & Tgt(void) const
Definition: InitialState.h:67
const int kPdgAntiLambda
Definition: PDGCodes.h:70
bool gAbortingInErr
Definition: Messenger.cxx:56
GENIE&#39;s GHEP MC event record.
Definition: GHepRecord.h:46
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:40
double fSSBarSuppression
ssbar suppression
Event finding and building.
#define pDEBUG
Definition: Messenger.h:64