PythiaHadronizationBase.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  Changes required to implement the GENIE Boosted Dark Matter module
11  were installed by Josh Berger (Univ. of Wisconsin)
12 */
13 //____________________________________________________________________________
14 
28 
29 using namespace genie;
30 using namespace genie::constants;
31 
32 //____________________________________________________________________________
35 {
36 
37 }
38 //____________________________________________________________________________
41 {
42 
43 }
44 //____________________________________________________________________________
46 EventRecordVisitorI(name, config)
47 {
48 
49 }
50 //____________________________________________________________________________
52 {
53 
54 }
55 //____________________________________________________________________________
57 {
58  Interaction * interaction = event->Summary();
59 
60  bool valid_process = this->AssertValidity(interaction);
61  if(!valid_process) {
62  LOG("PythiaHad", pFATAL)
63  << "Input interaction type is not allowed!!!";
64  LOG("PythiaHad", pFATAL)
65  << *event;
66  gAbortingInErr = true;
67  std::exit(1);
68  }
69 
70  // Decide the leading quark and remnant diquark PDG codes for this event
71  this->MakeQuarkDiquarkAssignments(interaction);
72 
73  // Copy original and set required PYTHIA decay flags
74  this->CopyOriginalDecayFlags();
75  this->SetDesiredDecayFlags();
76 
77  // Call PYTHIA6 or PYTHIA8 to obtain the fragmentation products
78  //TClonesArray * particle_list = this->Hadronize(interaction);
79  bool hadronized = this->Hadronize(event);
80 
81  // Restore decay flags
83 
84  if(!hadronized) {
85  LOG("PythiaHad", pWARN) << "Hadronization failed!";
86  event->EventFlags()->SetBitNumber(kHadroSysGenErr, true);
88  exception.SetReason("Could not simulate the hadronic system");
89  exception.SwitchOnFastForward();
90  throw exception;
91  return;
92  }
93 }
94 //____________________________________________________________________________
96  const Interaction * interaction) const
97 {
98  LOG("PythiaHad", pNOTICE)
99  << "Making leading quark / remnant di-quark assignments";
100 
101  // get kinematics / init-state / process-info
102 
103  const Kinematics & kinematics = interaction->Kine();
104  const InitialState & init_state = interaction->InitState();
105  const ProcessInfo & proc_info = interaction->ProcInfo();
106  const Target & target = init_state.Tgt();
107 
108  assert(target.HitQrkIsSet());
109 
110  double W = kinematics.W();
111 
112  int probe = init_state.ProbePdg();
113  int hit_nucleon = target.HitNucPdg();
114  int hit_quark = target.HitQrkPdg();
115  bool from_sea = target.HitSeaQrk();
116 
117  LOG("PythiaHad", pNOTICE)
118  << "Hit nucleon pdgc = " << hit_nucleon << ", W = " << W;
119  LOG("PythiaHad", pNOTICE)
120  << "Selected hit quark pdgc = " << hit_quark
121  << ((from_sea) ? "[sea]" : "[valence]");
122 
123  // check hit-nucleon assignment, input neutrino & interaction type
124  bool isp = pdg::IsProton (hit_nucleon);
125  bool isn = pdg::IsNeutron (hit_nucleon);
126  bool isv = pdg::IsNeutrino (probe);
127  bool isvb = pdg::IsAntiNeutrino (probe);
128 //bool isl = pdg::IsNegChargedLepton (probe);
129 //bool islb = pdg::IsPosChargedLepton (probe);
130  bool iscc = proc_info.IsWeakCC ();
131  bool isnc = proc_info.IsWeakNC ();
132  bool isdm = proc_info.IsDarkMatter ();
133  bool isem = proc_info.IsEM ();
134  bool isu = pdg::IsUQuark (hit_quark);
135  bool isd = pdg::IsDQuark (hit_quark);
136  bool iss = pdg::IsSQuark (hit_quark);
137  bool isub = pdg::IsAntiUQuark (hit_quark);
138  bool isdb = pdg::IsAntiDQuark (hit_quark);
139  bool issb = pdg::IsAntiSQuark (hit_quark);
140 
141  //
142  // Generate the quark system (q + qq) initiating the hadronization
143  //
144 
145  int leading_quark = 0; // leading quark (hit quark after the interaction)
146  int remnant_diquark = 0; // remnant diquark (xF<0 at hadronic CMS)
147 
148  // Figure out the what happens to the hit quark after the interaction
149  if (isnc || isem || isdm) {
150  // NC, EM
151  leading_quark = hit_quark;
152  } else {
153  // CC
154  if (isv && isd ) leading_quark = kPdgUQuark;
155  else if (isv && iss ) leading_quark = kPdgUQuark;
156  else if (isv && isub) leading_quark = kPdgAntiDQuark;
157  else if (isvb && isu ) leading_quark = kPdgDQuark;
158  else if (isvb && isdb) leading_quark = kPdgAntiUQuark;
159  else if (isvb && issb) leading_quark = kPdgAntiUQuark;
160  else {
161  LOG("PythiaHad", pERROR)
162  << "Not allowed mode. Refused to make a leading quark assignment!";
163  return;
164  }
165  }//CC
166 
167  // Figure out what the remnant diquark is.
168  // Note from Hugh, following a conversation with his local HEP theorist
169  // (Gary Goldstein): "I am told that the probability of finding the diquark
170  // in the singlet vs. triplet states is 50-50."
171 
172  // hit quark = valence quark
173  if(!from_sea) {
174  if (isp && isu) remnant_diquark = kPdgUDDiquarkS1; /* u(->q) + ud */
175  if (isp && isd) remnant_diquark = kPdgUUDiquarkS1; /* d(->q) + uu */
176  if (isn && isu) remnant_diquark = kPdgDDDiquarkS1; /* u(->q) + dd */
177  if (isn && isd) remnant_diquark = kPdgUDDiquarkS1; /* d(->q) + ud */
178  }
179  // hit quark = sea quark
180  else {
181  if(isp && isu) remnant_diquark = kPdgUDDiquarkS1; /* u(->q) + bar{u} uud (=ud) */
182  if(isp && isd) remnant_diquark = kPdgUUDiquarkS1; /* d(->q) + bar{d} uud (=uu) */
183  if(isn && isu) remnant_diquark = kPdgDDDiquarkS1; /* u(->q) + bar{u} udd (=dd) */
184  if(isn && isd) remnant_diquark = kPdgUDDiquarkS1; /* d(->q) + bar{d} udd (=ud) */
185 
186  // The following section needs revisiting.
187 
188  // The lepton is scattered off a sea antiquark, materializing its quark
189  // partner and leaving me with a 5q system ( <qbar + q> + qqq(valence) )
190  // I will force few qbar+q annhilations below to get my quark/diquark system
191  // Probably it is best to leave the qqq system in the final state and then
192  // just do the fragmentation of the qbar q system? But how do I figure out
193  // how to split the available energy?
194 
195  /* bar{u} (-> bar{d}) + u uud => u + uu */
196  if(isp && isub && iscc) {
197  leading_quark = kPdgUQuark;
198  remnant_diquark = kPdgUUDiquarkS1;
199  }
200  /* bar{u} (-> bar{u}) + u uud => u + ud */
201  if(isp && isub && (isnc||isem||isdm)) {
202  leading_quark = kPdgUQuark;
203  remnant_diquark = kPdgUDDiquarkS1;
204  }
205  /* bar{d} (-> bar{u}) + d uud => d + ud */
206  if(isp && isdb && iscc) {
207  leading_quark = kPdgDQuark;
208  remnant_diquark = kPdgUDDiquarkS1;
209  }
210  /* bar{d} (-> bar{d}) + d uud => d + uu */
211  if(isp && isdb && (isnc||isem||isdm)) {
212  leading_quark = kPdgDQuark;
213  remnant_diquark = kPdgUUDiquarkS1;
214  }
215  /* bar{u} (-> bar{d}) + u udd => u + ud */
216  if(isn && isub && iscc) {
217  leading_quark = kPdgUQuark;
218  remnant_diquark = kPdgUDDiquarkS1;
219  }
220  /* bar{u} (-> bar{u}) + u udd => u + dd */
221  if(isn && isub && (isnc||isem||isdm)) {
222  leading_quark = kPdgUQuark;
223  remnant_diquark = kPdgDDDiquarkS1;
224  }
225  /* bar{d} (-> bar{u}) + d udd => d + dd */
226  if(isn && isdb && iscc) {
227  leading_quark = kPdgDQuark;
228  remnant_diquark = kPdgDDDiquarkS1;
229  }
230  /* bar{d} (-> bar{d}) + d udd => d + ud */
231  if(isn && isdb && (isnc||isem||isdm)) {
232  leading_quark = kPdgDQuark;
233  remnant_diquark = kPdgUDDiquarkS1;
234  }
235 
236  // The neutrino is scatterred off s or sbar sea quarks
237  // For the time being I will handle s like d and sbar like dbar (copy & paste
238  // from above) so that I conserve charge.
239 
240  if(iss || issb) {
241  LOG("PythiaHad", pNOTICE)
242  << "Can not really handle a hit s or sbar quark / Faking it";
243 
244  if(isp && iss) { remnant_diquark = kPdgUUDiquarkS1; }
245  if(isn && iss) { remnant_diquark = kPdgUDDiquarkS1; }
246 
247  if(isp && issb && iscc) {
248  leading_quark = kPdgDQuark;
249  remnant_diquark = kPdgUDDiquarkS1;
250  }
251  if(isp && issb && (isnc||isem||isdm)) {
252  leading_quark = kPdgDQuark;
253  remnant_diquark = kPdgUUDiquarkS1;
254  }
255  if(isn && issb && iscc) {
256  leading_quark = kPdgDQuark;
257  remnant_diquark = kPdgDDDiquarkS1;
258  }
259  if(isn && issb && (isnc||isem||isdm)) {
260  leading_quark = kPdgDQuark;
261  remnant_diquark = kPdgUDDiquarkS1;
262  }
263  }
264 
265  // if the diquark is a ud, switch it to the singlet state with 50% probability
266  if(remnant_diquark == kPdgUDDiquarkS1) {
267  RandomGen * rnd = RandomGen::Instance();
268  double Rqq = rnd->RndHadro().Rndm();
269  if(Rqq<0.5) remnant_diquark = kPdgUDDiquarkS0;
270  }
271  }
272 
273  fLeadingQuark = leading_quark;
274  fRemnantDiquark = remnant_diquark;
275 }
276 //____________________________________________________________________________
278 
279  // check that there is no charm production
280  // (GENIE uses a special model for these cases)
281  if(interaction->ExclTag().IsCharmEvent()) {
282  LOG("PythiaHad", pWARN) << "Can't hadronize charm events";
283  return false;
284  }
285  // check the available mass
286  double W = utils::kinematics::W(interaction);
287  double Wmin = kNucleonMass+kPionMass;
288  if(W < Wmin) {
289  LOG("PythiaHad", pWARN) << "Low invariant mass, W = "
290  << W << " GeV!!";
291  return false;
292  }
293 
294  const InitialState & init_state = interaction->InitState();
295  const ProcessInfo & proc_info = interaction->ProcInfo();
296  const Target & target = init_state.Tgt();
297 
298  if( ! target.HitQrkIsSet() ) {
299  LOG("PythiaHad", pWARN) << "Hit quark was not set!";
300  return false;
301  }
302 
303  int probe = init_state.ProbePdg();
304  int hit_nucleon = target.HitNucPdg();
305  int hit_quark = target.HitQrkPdg();
306  //bool from_sea = target.HitSeaQrk();
307 
308  // check hit-nucleon assignment, input neutrino & weak current
309  bool isp = pdg::IsProton (hit_nucleon);
310  bool isn = pdg::IsNeutron (hit_nucleon);
311  bool isv = pdg::IsNeutrino (probe);
312  bool isvb = pdg::IsAntiNeutrino (probe);
313  bool isdm = pdg::IsDarkMatter (probe);
314  bool isl = pdg::IsNegChargedLepton (probe);
315  bool islb = pdg::IsPosChargedLepton (probe);
316  bool iscc = proc_info.IsWeakCC ();
317  bool isnc = proc_info.IsWeakNC ();
318  bool isdmi = proc_info.IsDarkMatter ();
319  bool isem = proc_info.IsEM ();
320  if( !(iscc||isnc||isem||isdmi) ) {
321  LOG("PythiaHad", pWARN)
322  << "Can only handle electro-weak interactions";
323  return false;
324  }
325  if( !(isp||isn) || !(isv||isvb||isl||islb||isdm) ) {
326  LOG("PythiaHad", pWARN)
327  << "Invalid initial state: probe = "
328  << probe << ", hit_nucleon = " << hit_nucleon;
329  return false;
330  }
331 
332  // assert that the interaction mode is allowed
333  bool isu = pdg::IsUQuark (hit_quark);
334  bool isd = pdg::IsDQuark (hit_quark);
335  bool iss = pdg::IsSQuark (hit_quark);
336  bool isub = pdg::IsAntiUQuark (hit_quark);
337  bool isdb = pdg::IsAntiDQuark (hit_quark);
338  bool issb = pdg::IsAntiSQuark (hit_quark);
339 
340  bool allowed = (iscc && isv && (isd||isub||iss)) ||
341  (iscc && isvb && (isu||isdb||issb)) ||
342  (isnc && (isv||isvb) && (isu||isd||isub||isdb||iss||issb)) ||
343  (isdmi && isdm && (isu||isd||isub||isdb||iss||issb)) ||
344  (isem && (isl||islb) && (isu||isd||isub||isdb||iss||issb));
345  if(!allowed) {
346  LOG("PythiaHad", pWARN)
347  << "Impossible interaction type / probe / hit quark combination!";
348  return false;
349  }
350 
351  return true;
352 }
353 //____________________________________________________________________________
355 {
356  fLeadingQuark = 0;
357  fRemnantDiquark = 0;
358  fSSBarSuppression = 0.;
359  fGaussianPt2 = 0.;
360  fNonGaussianPt2Tail = 0.;
361  fRemainingECutoff = 0.;
362  fDiQuarkSuppression = 0.;
364  fSVMesonSuppression = 0.;
365  fLunda = 0.;
366  fLundb = 0.;
367  fLundaDiq = 0.;
368  fOriDecayFlag_pi0 = false;
369  fOriDecayFlag_K0 = false;
370  fOriDecayFlag_K0b = false;
371  fOriDecayFlag_L0 = false;
372  fOriDecayFlag_L0b = false;
373  fOriDecayFlag_Dm = false;
374  fOriDecayFlag_D0 = false;
375  fOriDecayFlag_Dp = false;
376  fOriDecayFlag_Dpp = false;
377  fReqDecayFlag_pi0 = false;
378  fReqDecayFlag_K0 = false;
379  fReqDecayFlag_K0b = false;
380  fReqDecayFlag_L0 = false;
381  fReqDecayFlag_L0b = false;
382  fReqDecayFlag_Dm = false;
383  fReqDecayFlag_D0 = false;
384  fReqDecayFlag_Dp = false;
385  fReqDecayFlag_Dpp = false;
386 }
387 //____________________________________________________________________________
389 {
390  // Get PYTHIA physics configuration parameters specified by GENIE
391  this->GetParam( "PYTHIA-SSBarSuppression", fSSBarSuppression );
392  this->GetParam( "PYTHIA-GaussianPt2", fGaussianPt2 );
393  this->GetParam( "PYTHIA-NonGaussianPt2Tail", fNonGaussianPt2Tail );
394  this->GetParam( "PYTHIA-RemainingEnergyCutoff", fRemainingECutoff );
395  this->GetParam( "PYTHIA-DiQuarkSuppression", fDiQuarkSuppression );
396  this->GetParam( "PYTHIA-LightVMesonSuppression", fLightVMesonSuppression );
397  this->GetParam( "PYTHIA-SVMesonSuppression", fSVMesonSuppression );
398  this->GetParam( "PYTHIA-Lunda", fLunda );
399  this->GetParam( "PYTHIA-Lundb", fLundb );
400  this->GetParam( "PYTHIA-LundaDiq", fLundaDiq );
401 
402  // Set required PYTHIA decay flags
403  fReqDecayFlag_pi0 = false; // don't decay pi0
404  fReqDecayFlag_K0 = false; // don't decay K0
405  fReqDecayFlag_K0b = false; // don't decay \bar{K0}
406  fReqDecayFlag_L0 = false; // don't decay Lambda0
407  fReqDecayFlag_L0b = false; // don't decay \bar{Lambda0}
408  fReqDecayFlag_Dm = true; // decay Delta-
409  fReqDecayFlag_D0 = true; // decay Delta0
410  fReqDecayFlag_Dp = true; // decay Delta+
411  fReqDecayFlag_Dpp = true; // decay Delta++
412 
413  // Load Wcut determining the phase space area where the multiplicity prob.
414  // scaling factors would be applied -if requested-
415  double Wcut, Wmin ;
416  this->GetParam( "Wcut", Wcut );
417  this->GetParam( "KNO2PYTHIA-Wmin", Wmin );
418 
419  if ( Wcut > Wmin ) {
420  LOG("PythiaHad", pERROR)
421  << "Wcut value too high and in conflict with the KNO2PYTHIA-Wmin!"
422  << "\n Wcut = " << Wcut
423  << "\n KNO2PYTHIA-Wmin = " << Wmin;
424  }
425 }
426 //____________________________________________________________________________
static QCString name
Definition: declinfo.cpp:673
virtual bool Hadronize(GHepRecord *event) const =0
const int kPdgUUDiquarkS1
Definition: PDGCodes.h:58
double W(bool selected=false) const
Definition: Kinematics.cxx:167
Basic constants.
bool HitSeaQrk(void) const
Definition: Target.cxx:316
bool IsWeakCC(void) const
double fGaussianPt2
gaussian pt2 distribution width
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:108
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:26
#define pERROR
Definition: Messenger.h:60
static const double kNucleonMass
Definition: Constants.h:78
bool IsUQuark(int pdgc)
Definition: PDGUtils.cxx:255
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
int HitNucPdg(void) const
Definition: Target.cxx:321
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the &#39;Visito...
int HitQrkPdg(void) const
Definition: Target.cxx:259
#define pFATAL
Definition: Messenger.h:57
const int kPdgUQuark
Definition: PDGCodes.h:42
Generated/set kinematical variables for an event.
Definition: Kinematics.h:40
double fRemainingECutoff
remaining E cutoff stopping fragmentation
bool IsDarkMatter(int pdgc)
Definition: PDGUtils.cxx:125
virtual void MakeQuarkDiquarkAssignments(const Interaction *in) const
bool IsSQuark(int pdgc)
Definition: PDGUtils.cxx:265
bool IsAntiSQuark(int pdgc)
Definition: PDGUtils.cxx:285
double fDiQuarkSuppression
di-quark suppression parameter
double fLundaDiq
adjustment of Lund a for di-quark
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:30
bool IsAntiDQuark(int pdgc)
Definition: PDGUtils.cxx:280
double fSVMesonSuppression
strange vector meson suppression
bool IsCharmEvent(void) const
Definition: XclsTag.h:50
double W(const Interaction *const i)
Definition: KineUtils.cxx:1031
bool IsNeutron(int pdgc)
Definition: PDGUtils.cxx:310
bool IsPosChargedLepton(int pdgc)
Definition: PDGUtils.cxx:146
Summary information for an interaction.
Definition: Interaction.h:55
const int kPdgAntiUQuark
Definition: PDGCodes.h:43
An exception thrown by EventRecordVisitorI when the normal processing sequence has to be disrupted (f...
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:305
bool IsWeakNC(void) const
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:97
virtual bool AssertValidity(const Interaction *in) const
const int kPdgUDDiquarkS1
Definition: PDGCodes.h:57
static Config * config
Definition: config.cpp:1054
A class encapsulating an enumeration of interaction types (EM, Weak-CC, Weak-NC) and scattering types...
Definition: ProcessInfo.h:43
bool IsAntiNeutrino(int pdgc)
Definition: PDGUtils.cxx:116
const int kPdgAntiDQuark
Definition: PDGCodes.h:45
const Kinematics & Kine(void) const
Definition: Interaction.h:70
A Neutrino Interaction Target. Is a transparent encapsulation of quite different physical systems suc...
Definition: Target.h:41
int ProbePdg(void) const
Definition: InitialState.h:65
const int kPdgDQuark
Definition: PDGCodes.h:44
virtual void SetDesiredDecayFlags(void) const =0
virtual void ProcessEventRecord(GHepRecord *event) const
const int kPdgUDDiquarkS0
Definition: PDGCodes.h:56
#define pWARN
Definition: Messenger.h:61
bool IsEM(void) const
virtual void CopyOriginalDecayFlags(void) const =0
TRandom3 & RndHadro(void) const
rnd number generator used by hadronization models
Definition: RandomGen.h:54
virtual void RestoreOriginalDecayFlags(void) const =0
static const double kPionMass
Definition: Constants.h:74
bool HitQrkIsSet(void) const
Definition: Target.cxx:309
bool IsDarkMatter(void) const
double fLightVMesonSuppression
light vector meson suppression
const XclsTag & ExclTag(void) const
Definition: Interaction.h:71
bool IsDQuark(int pdgc)
Definition: PDGUtils.cxx:260
const InitialState & InitState(void) const
Definition: Interaction.h:68
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:69
#define pNOTICE
Definition: Messenger.h:62
double fNonGaussianPt2Tail
non gaussian pt2 tail parameterization
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
const Target & Tgt(void) const
Definition: InitialState.h:67
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...
bool IsNegChargedLepton(int pdgc)
Definition: PDGUtils.cxx:137
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double fSSBarSuppression
ssbar suppression
Event finding and building.
bool IsAntiUQuark(int pdgc)
Definition: PDGUtils.cxx:275
Initial State information.
Definition: InitialState.h:49
const int kPdgDDDiquarkS1
Definition: PDGCodes.h:55