PythiaHadronization.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 
15 #include <RVersion.h>
16 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,6)
17 #include <TMCParticle.h>
18 #else
19 #include <TMCParticle6.h>
20 #endif
21 #include <TClonesArray.h>
22 #include <TMath.h>
23 #include <TH1D.h>
24 
27 #include "Framework/Conventions/GBuild.h"
38 
39 using namespace genie;
40 using namespace genie::constants;
41 
42 // the actual PYTHIA call
43 extern "C" void py2ent_(int *, int *, int *, double *);
44 
45 //____________________________________________________________________________
47 HadronizationModelBase("genie::PythiaHadronization")
48 {
49  this->Initialize();
50 }
51 //____________________________________________________________________________
53 HadronizationModelBase("genie::PythiaHadronization", config)
54 {
55  this->Initialize();
56 }
57 //____________________________________________________________________________
59 {
60 
61 }
62 //____________________________________________________________________________
64 {
65  fPythia = TPythia6::Instance();
66 
67  // sync GENIE/PYTHIA6 seed number
69 }
70 //____________________________________________________________________________
71 TClonesArray *
73  const Interaction * interaction) const
74 {
75  LOG("PythiaHad", pNOTICE) << "Running PYTHIA hadronizer";
76 
77  if(!this->AssertValidity(interaction)) {
78  LOG("PythiaHad", pERROR) << "Returning a null particle list!";
79  return 0;
80  }
81 
82  // get kinematics / init-state / process-info
83 
84  const Kinematics & kinematics = interaction->Kine();
85  const InitialState & init_state = interaction->InitState();
86  const ProcessInfo & proc_info = interaction->ProcInfo();
87  const Target & target = init_state.Tgt();
88 
89  assert(target.HitQrkIsSet());
90 
91  double W = kinematics.W();
92 
93  int probe = init_state.ProbePdg();
94  int hit_nucleon = target.HitNucPdg();
95  int hit_quark = target.HitQrkPdg();
96  bool from_sea = target.HitSeaQrk();
97 
98  LOG("PythiaHad", pNOTICE)
99  << "Hit nucleon pdgc = " << hit_nucleon << ", W = " << W;
100  LOG("PythiaHad", pNOTICE)
101  << "Selected hit quark pdgc = " << hit_quark
102  << ((from_sea) ? "[sea]" : "[valence]");
103 
104  // check hit-nucleon assignment, input neutrino & interaction type
105  bool isp = pdg::IsProton (hit_nucleon);
106  bool isn = pdg::IsNeutron (hit_nucleon);
107  bool isv = pdg::IsNeutrino (probe);
108  bool isvb = pdg::IsAntiNeutrino (probe);
109 //bool isl = pdg::IsNegChargedLepton (probe);
110 //bool islb = pdg::IsPosChargedLepton (probe);
111  bool iscc = proc_info.IsWeakCC ();
112  bool isnc = proc_info.IsWeakNC ();
113  bool isdm = proc_info.IsDarkMatter ();
114  bool isem = proc_info.IsEM ();
115  bool isu = pdg::IsUQuark (hit_quark);
116  bool isd = pdg::IsDQuark (hit_quark);
117  bool iss = pdg::IsSQuark (hit_quark);
118  bool isub = pdg::IsAntiUQuark (hit_quark);
119  bool isdb = pdg::IsAntiDQuark (hit_quark);
120  bool issb = pdg::IsAntiSQuark (hit_quark);
121 
122  //
123  // Generate the quark system (q + qq) initiating the hadronization
124  //
125 
126  int final_quark = 0; // leading quark (hit quark after the interaction)
127  int diquark = 0; // remnant diquark (xF<0 at hadronic CMS)
128 
129  // Figure out the what happens to the hit quark after the interaction
130  if (isnc || isem || isdm) {
131  // NC, EM
132  final_quark = hit_quark;
133  } else {
134  // CC
135  if (isv && isd ) final_quark = kPdgUQuark;
136  else if (isv && iss ) final_quark = kPdgUQuark;
137  else if (isv && isub) final_quark = kPdgAntiDQuark;
138  else if (isvb && isu ) final_quark = kPdgDQuark;
139  else if (isvb && isdb) final_quark = kPdgAntiUQuark;
140  else if (isvb && issb) final_quark = kPdgAntiUQuark;
141  else {
142  LOG("PythiaHad", pERROR)
143  << "Not allowed mode. Refused to make a final quark assignment!";
144  return 0;
145  }
146  }//CC
147 
148  // Figure out what the remnant diquark is.
149  // Note from Hugh, following a conversation with his local HEP theorist
150  // (Gary Goldstein): "I am told that the probability of finding the diquark
151  // in the singlet vs. triplet states is 50-50."
152 
153  // hit quark = valence quark
154  if(!from_sea) {
155  if (isp && isu) diquark = kPdgUDDiquarkS1; /* u(->q) + ud */
156  if (isp && isd) diquark = kPdgUUDiquarkS1; /* d(->q) + uu */
157  if (isn && isu) diquark = kPdgDDDiquarkS1; /* u(->q) + dd */
158  if (isn && isd) diquark = kPdgUDDiquarkS1; /* d(->q) + ud */
159  }
160  // hit quark = sea quark
161  else {
162  if(isp && isu) diquark = kPdgUDDiquarkS1; /* u(->q) + bar{u} uud (=ud) */
163  if(isp && isd) diquark = kPdgUUDiquarkS1; /* d(->q) + bar{d} uud (=uu) */
164  if(isn && isu) diquark = kPdgDDDiquarkS1; /* u(->q) + bar{u} udd (=dd) */
165  if(isn && isd) diquark = kPdgUDDiquarkS1; /* d(->q) + bar{d} udd (=ud) */
166 
167  // The following section needs revisiting.
168 
169  // The lepton is scattered off a sea antiquark, materializing its quark
170  // partner and leaving me with a 5q system ( <qbar + q> + qqq(valence) )
171  // I will force few qbar+q annhilations below to get my quark/diquark system
172  // Probably it is best to leave the qqq system in the final state and then
173  // just do the fragmentation of the qbar q system? But how do I figure out
174  // how to split the available energy?
175 
176  /* bar{u} (-> bar{d}) + u uud => u + uu */
177  if(isp && isub && iscc) {final_quark = kPdgUQuark; diquark = kPdgUUDiquarkS1;}
178  /* bar{u} (-> bar{u}) + u uud => u + ud */
179  if(isp && isub && (isnc||isem||isdm)) {final_quark = kPdgUQuark; diquark = kPdgUDDiquarkS1;}
180  /* bar{d} (-> bar{u}) + d uud => d + ud */
181  if(isp && isdb && iscc) {final_quark = kPdgDQuark; diquark = kPdgUDDiquarkS1;}
182  /* bar{d} (-> bar{d}) + d uud => d + uu */
183  if(isp && isdb && (isnc||isem||isdm)) {final_quark = kPdgDQuark; diquark = kPdgUUDiquarkS1;}
184  /* bar{u} (-> bar{d}) + u udd => u + ud */
185  if(isn && isub && iscc) {final_quark = kPdgUQuark; diquark = kPdgUDDiquarkS1;}
186  /* bar{u} (-> bar{u}) + u udd => u + dd */
187  if(isn && isub && (isnc||isem||isdm)) {final_quark = kPdgUQuark; diquark = kPdgDDDiquarkS1;}
188  /* bar{d} (-> bar{u}) + d udd => d + dd */
189  if(isn && isdb && iscc) {final_quark = kPdgDQuark; diquark = kPdgDDDiquarkS1;}
190  /* bar{d} (-> bar{d}) + d udd => d + ud */
191  if(isn && isdb && (isnc||isem||isdm)) {final_quark = kPdgDQuark; diquark = kPdgUDDiquarkS1;}
192 
193  // The neutrino is scatterred off s or sbar sea quarks
194  // For the time being I will handle s like d and sbar like dbar (copy & paste
195  // from above) so that I conserve charge.
196 
197  if(iss || issb) {
198  LOG("PythiaHad", pNOTICE)
199  << "Can not really handle a hit s or sbar quark / Faking it";
200 
201  if(isp && iss) { diquark = kPdgUUDiquarkS1; }
202  if(isn && iss) { diquark = kPdgUDDiquarkS1; }
203 
204  if(isp && issb && iscc) {final_quark = kPdgDQuark; diquark = kPdgUDDiquarkS1;}
205  if(isp && issb && (isnc||isem||isdm)) {final_quark = kPdgDQuark; diquark = kPdgUUDiquarkS1;}
206  if(isn && issb && iscc) {final_quark = kPdgDQuark; diquark = kPdgDDDiquarkS1;}
207  if(isn && issb && (isnc||isem||isdm)) {final_quark = kPdgDQuark; diquark = kPdgUDDiquarkS1;}
208  }
209 
210  // if the diquark is a ud, switch it to the singlet state with 50% probability
211  if(diquark == kPdgUDDiquarkS1) {
212  RandomGen * rnd = RandomGen::Instance();
213  double Rqq = rnd->RndHadro().Rndm();
214  if(Rqq<0.5) diquark = kPdgUDDiquarkS0;
215  }
216  }
217  assert(diquark!=0);
218 
219  //
220  // PYTHIA -> HADRONIZATION
221  //
222 
223  LOG("PythiaHad", pNOTICE)
224  << "Fragmentation / Init System: "
225  << "q = " << final_quark << ", qq = " << diquark;
226  int ip = 0;
227 
228  // Determine how jetset treats un-stable particles appearing in hadronization
229 
230  int pi0_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgPi0), 1);
231  int K0_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgK0), 1);
232  int K0b_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgAntiK0), 1);
233  int L0_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgLambda), 1);
234  int L0b_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgAntiLambda), 1);
235  int Dm_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaM), 1);
236  int D0_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_Delta0), 1);
237  int Dp_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaP), 1);
238  int Dpp_decflag = fPythia->GetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaPP), 1);
239 
240 #ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
241  LOG("PythiaHad", pDEBUG) << "Original decay flag for pi0 = " << pi0_decflag;
242  LOG("PythiaHad", pDEBUG) << "Original decay flag for K0 = " << K0_decflag;
243  LOG("PythiaHad", pDEBUG) << "Original decay flag for \bar{K0} = " << K0b_decflag;
244  LOG("PythiaHad", pDEBUG) << "Original decay flag for Lambda = " << L0_decflag;
245  LOG("PythiaHad", pDEBUG) << "Original decay flag for \bar{Lambda0} = " << L0b_decflag;
246  LOG("PythiaHad", pDEBUG) << "Original decay flag for D- = " << Dm_decflag;
247  LOG("PythiaHad", pDEBUG) << "Original decay flag for D0 = " << D0_decflag;
248  LOG("PythiaHad", pDEBUG) << "Original decay flag for D+ = " << Dp_decflag;
249  LOG("PythiaHad", pDEBUG) << "Original decay flag for D++ = " << Dpp_decflag;
250 #endif
251 
252  fPythia->SetMDCY(fPythia->Pycomp(kPdgPi0), 1,0); // don't decay pi0
253  fPythia->SetMDCY(fPythia->Pycomp(kPdgK0), 1,0); // don't decay K0
254  fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiK0), 1,0); // don't decay \bar{K0}
255  fPythia->SetMDCY(fPythia->Pycomp(kPdgLambda), 1,0); // don't decay Lambda0
256  fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiLambda), 1,0); // don't decay \bar{Lambda0}
257  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaM), 1,1); // decay Delta-
258  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_Delta0), 1,1); // decay Delta0
259  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaP), 1,1); // decay Delta+
260  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaPP), 1,1); // decay Delta++
261 
262  // -- hadronize --
263  py2ent_(&ip, &final_quark, &diquark, &W); // hadronizer
264 
265  // restore pythia decay settings so as not to interfere with decayer
266  fPythia->SetMDCY(fPythia->Pycomp(kPdgPi0), 1, pi0_decflag);
267  fPythia->SetMDCY(fPythia->Pycomp(kPdgK0), 1, K0_decflag);
268  fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiK0), 1, K0b_decflag);
269  fPythia->SetMDCY(fPythia->Pycomp(kPdgLambda), 1, L0_decflag);
270  fPythia->SetMDCY(fPythia->Pycomp(kPdgAntiLambda), 1, L0b_decflag);
271  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaM), 1, Dm_decflag);
272  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_Delta0), 1, D0_decflag);
273  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaP), 1, Dp_decflag);
274  fPythia->SetMDCY(fPythia->Pycomp(kPdgP33m1232_DeltaPP), 1, Dpp_decflag);
275 
276  // get LUJETS record
277  fPythia->GetPrimaries();
278  TClonesArray * pythia_particles =
279  (TClonesArray *) fPythia->ImportParticles("All");
280 
281  // copy PYTHIA container to a new TClonesArray so as to transfer ownership
282  // of the container and of its elements to the calling method
283 
284  int np = pythia_particles->GetEntries();
285  assert(np>0);
286  TClonesArray * particle_list = new TClonesArray("TMCParticle", np);
287  particle_list->SetOwner(true);
288 
289  unsigned int i = 0;
290  TMCParticle * particle = 0;
291  TIter particle_iter(pythia_particles);
292 
293  while( (particle = (TMCParticle *) particle_iter.Next()) ) {
294  LOG("PythiaHad", pDEBUG)
295  << "Adding final state particle pdgc = " << particle->GetKF()
296  << " with status = " << particle->GetKS();
297 
298  if(particle->GetKS() == 1) {
299  if( pdg::IsQuark (particle->GetKF()) ||
300  pdg::IsDiQuark(particle->GetKF()) ) {
301  LOG("PythiaHad", pERROR)
302  << "Hadronization failed! Bare quark/di-quarks appear in final state!";
303  particle_list->Delete();
304  delete particle_list;
305  return 0;
306  }
307  }
308 
309  // fix numbering scheme used for mother/daughter assignments
310  particle->SetParent (particle->GetParent() - 1);
311  particle->SetFirstChild (particle->GetFirstChild() - 1);
312  particle->SetLastChild (particle->GetLastChild() - 1);
313 
314  // insert the particle in the list
315  new ( (*particle_list)[i++] ) TMCParticle(*particle);
316  }
317 
318  utils::fragmrec::Print(particle_list);
319  return particle_list;
320 }
321 //____________________________________________________________________________
322 PDGCodeList *
324  const Interaction * interaction) const
325 {
326 // Works the opposite way (compared with the KNO hadronization model)
327 // Rather than having this method as one of the hadronization model components,
328 // we extract the list of particles from the fragmentation record after the
329 // hadronization has been completed.
330 
331  TClonesArray * particle_list = this->Hadronize(interaction);
332 
333  if(!particle_list) return 0;
334 
335  bool allowdup=true;
336  PDGCodeList * pdgcv = new PDGCodeList(allowdup);
337  pdgcv->reserve(particle_list->GetEntries());
338 
339  TMCParticle * particle = 0;
340  TIter particle_iter(particle_list);
341 
342  while ((particle = (TMCParticle *) particle_iter.Next()))
343  {
344  if (particle->GetKS()==1) pdgcv->push_back(particle->GetKF());
345  }
346  particle_list->Delete();
347  delete particle_list;
348 
349  return pdgcv;
350 }
351 //____________________________________________________________________________
353  const Interaction * interaction, Option_t * opt) const
354 {
355 // Similar comments apply as in SelectParticles()
356 
357  if(!this->AssertValidity(interaction)) {
358  LOG("PythiaHad", pWARN)
359  << "Returning a null multipicity probability distribution!";
360  return 0;
361  }
362  double maxmult = this->MaxMult(interaction);
363  TH1D * mult_prob = this->CreateMultProbHist(maxmult);
364 
365  const int nev=500;
366  TMCParticle * particle = 0;
367 
368  for(int iev=0; iev<nev; iev++) {
369 
370  TClonesArray * particle_list = this->Hadronize(interaction);
371  double weight = this->Weight();
372 
373  if(!particle_list) { iev--; continue; }
374 
375  int n = 0;
376  TIter particle_iter(particle_list);
377  while ((particle = (TMCParticle *) particle_iter.Next()))
378  {
379  if (particle->GetKS()==1) n++;
380  }
381  particle_list->Delete();
382  delete particle_list;
383  mult_prob->Fill( (double)n, weight);
384  }
385 
386  double integral = mult_prob->Integral("width");
387  if(integral>0) {
388  // Normalize the probability distribution
389  mult_prob->Scale(1.0/integral);
390  } else {
391  SLOG("PythiaHad", pWARN) << "probability distribution integral = 0";
392  return mult_prob;
393  }
394 
395  string option(opt);
396 
397  bool apply_neugen_Rijk = option.find("+LowMultSuppr") != string::npos;
398  bool renormalize = option.find("+Renormalize") != string::npos;
399 
400  // Apply the NeuGEN probability scaling factors -if requested-
401  if(apply_neugen_Rijk) {
402  SLOG("KNOHad", pINFO) << "Applying NeuGEN scaling factors";
403  // Only do so for W<Wcut
404  const Kinematics & kinematics = interaction->Kine();
405  double W = kinematics.W();
406  if(W<fWcut) {
407  this->ApplyRijk(interaction, renormalize, mult_prob);
408  } else {
409  SLOG("PythiaHad", pDEBUG)
410  << "W = " << W << " < Wcut = " << fWcut
411  << " - Will not apply scaling factors";
412  }//<wcut?
413  }//apply?
414 
415  return mult_prob;
416 }
417 //____________________________________________________________________________
418 double PythiaHadronization::Weight(void) const
419 {
420  return 1.; // does not generate weighted events
421 }
422 //____________________________________________________________________________
424 {
425  Algorithm::Configure(config);
426  this->LoadConfig();
427 }
428 //____________________________________________________________________________
430 {
431  Algorithm::Configure(config);
432  this->LoadConfig();
433 }
434 //____________________________________________________________________________
436 {
437  // the configurable PYTHIA parameters used here are the ones used by NUX
438  // (see A.Rubbia's talk @ NuINT-01)
439  // The defaults are the values used by PYTHIA
440  // Use the NUX config set to set the tuned values as used in NUX.
441 
442  GetParam( "PYTHIA-SSBarSuppression", fSSBarSuppression ) ;
443  GetParam( "PYTHIA-GaussianPt2", fGaussianPt2 ) ;
444  GetParam( "PYTHIA-NonGaussianPt2Tail", fNonGaussianPt2Tail ) ;
445  GetParam( "PYTHIA-RemainingEnergyCutoff", fRemainingECutoff ) ;
446 
447  GetParam( "PYTHIA-DiQuarkSuppression", fDiQuarkSuppression ) ;
448  GetParam( "PYTHIA-LightVMesonSuppression", fLightVMesonSuppression ) ;
449  GetParam( "PYTHIA-SVMesonSuppression", fSVMesonSuppression ) ;
450  GetParam( "PYTHIA-Lunda", fLunda ) ;
451  GetParam( "PYTHIA-Lundb", fLundb ) ;
452  GetParam( "PYTHIA-LundaDiq", fLundaDiq ) ;
453 
454  fPythia->SetPARJ(1, fDiQuarkSuppression ) ;
455  fPythia->SetPARJ(11, fLightVMesonSuppression ) ;
456  fPythia->SetPARJ(12, fSVMesonSuppression ) ;
457  fPythia->SetPARJ(41, fLunda ) ;
458  fPythia->SetPARJ(42, fLundb ) ;
459  fPythia->SetPARJ(45, fLundaDiq ) ;
460 
461  fPythia->SetPARJ(2, fSSBarSuppression);
462  fPythia->SetPARJ(21, fGaussianPt2);
463  fPythia->SetPARJ(23, fNonGaussianPt2Tail);
464  fPythia->SetPARJ(33, fRemainingECutoff);
465 
466  // Load Wcut determining the phase space area where the multiplicity prob.
467  // scaling factors would be applied -if requested-
468  GetParam( "Wcut", fWcut ) ;
469 
470  // decayer
471  fDecayer = 0;
472  if( GetConfig().Exists("Decayer") ) {
473  fDecayer = dynamic_cast<const DecayModelI *> (this->SubAlg("Decayer"));
474  assert(fDecayer);
475  }
476 
477  // Load NEUGEN multiplicity probability scaling parameters Rijk
478  //neutrinos
479  GetParam( "DIS-HMultWgt-vp-CC-m2", fRvpCCm2 ) ;
480  GetParam( "DIS-HMultWgt-vp-CC-m3", fRvpCCm3 ) ;
481  GetParam( "DIS-HMultWgt-vp-NC-m2", fRvpNCm2 ) ;
482  GetParam( "DIS-HMultWgt-vp-NC-m3", fRvpNCm3 ) ;
483  GetParam( "DIS-HMultWgt-vn-CC-m2", fRvnCCm2 ) ;
484  GetParam( "DIS-HMultWgt-vn-CC-m3", fRvnCCm3 ) ;
485  GetParam( "DIS-HMultWgt-vn-NC-m2", fRvnNCm2 ) ;
486  GetParam( "DIS-HMultWgt-vn-NC-m3", fRvnNCm3 ) ;
487  //Anti-neutrinos
488  GetParam( "DIS-HMultWgt-vbp-CC-m2", fRvbpCCm2 ) ;
489  GetParam( "DIS-HMultWgt-vbp-CC-m3", fRvbpCCm3 ) ;
490  GetParam( "DIS-HMultWgt-vbp-NC-m2", fRvbpNCm2 ) ;
491  GetParam( "DIS-HMultWgt-vbp-NC-m3", fRvbpNCm3 ) ;
492  GetParam( "DIS-HMultWgt-vbn-CC-m2", fRvbnCCm2 ) ;
493  GetParam( "DIS-HMultWgt-vbn-CC-m3", fRvbnCCm3 ) ;
494  GetParam( "DIS-HMultWgt-vbn-NC-m2", fRvbnNCm2 ) ;
495  GetParam( "DIS-HMultWgt-vbn-NC-m3", fRvbnNCm3 ) ;
496 
497  LOG("PythiaHad", pDEBUG) << GetConfig() ;
498 }
499 //____________________________________________________________________________
501 {
502  // check that there is no charm production
503  // (GENIE uses a special model for these cases)
504  if(interaction->ExclTag().IsCharmEvent()) {
505  LOG("PythiaHad", pWARN) << "Can't hadronize charm events";
506  return false;
507  }
508  // check the available mass
509  double W = utils::kinematics::W(interaction);
510  if(W < this->Wmin()) {
511  LOG("PythiaHad", pWARN) << "Low invariant mass, W = " << W << " GeV!!";
512  return false;
513  }
514 
515  const InitialState & init_state = interaction->InitState();
516  const ProcessInfo & proc_info = interaction->ProcInfo();
517  const Target & target = init_state.Tgt();
518 
519  if( ! target.HitQrkIsSet() ) {
520  LOG("PythiaHad", pWARN) << "Hit quark was not set!";
521  return false;
522  }
523 
524  int probe = init_state.ProbePdg();
525  int hit_nucleon = target.HitNucPdg();
526  int hit_quark = target.HitQrkPdg();
527 //bool from_sea = target.HitSeaQrk();
528 
529  // check hit-nucleon assignment, input neutrino & weak current
530  bool isp = pdg::IsProton (hit_nucleon);
531  bool isn = pdg::IsNeutron (hit_nucleon);
532  bool isv = pdg::IsNeutrino (probe);
533  bool isvb = pdg::IsAntiNeutrino (probe);
534  bool isdm = pdg::IsDarkMatter (probe);
535  bool isl = pdg::IsNegChargedLepton (probe);
536  bool islb = pdg::IsPosChargedLepton (probe);
537  bool iscc = proc_info.IsWeakCC ();
538  bool isnc = proc_info.IsWeakNC ();
539  bool isdmi = proc_info.IsDarkMatter ();
540  bool isem = proc_info.IsEM ();
541  if( !(iscc||isnc||isem||isdmi) ) {
542  LOG("PythiaHad", pWARN)
543  << "Can only handle electro-weak interactions";
544  return false;
545  }
546  if( !(isp||isn) || !(isv||isvb||isl||islb||isdm) ) {
547  LOG("PythiaHad", pWARN)
548  << "Invalid initial state: probe = "
549  << probe << ", hit_nucleon = " << hit_nucleon;
550  return false;
551  }
552 
553  // assert that the interaction mode is allowed
554  bool isu = pdg::IsUQuark (hit_quark);
555  bool isd = pdg::IsDQuark (hit_quark);
556  bool iss = pdg::IsSQuark (hit_quark);
557  bool isub = pdg::IsAntiUQuark (hit_quark);
558  bool isdb = pdg::IsAntiDQuark (hit_quark);
559  bool issb = pdg::IsAntiSQuark (hit_quark);
560 
561  bool allowed = (iscc && isv && (isd||isub||iss)) ||
562  (iscc && isvb && (isu||isdb||issb)) ||
563  (isnc && (isv||isvb) && (isu||isd||isub||isdb||iss||issb)) ||
564  (isdmi && isdm && (isu||isd||isub||isdb||iss||issb)) ||
565  (isem && (isl||islb) && (isu||isd||isub||isdb||iss||issb));
566  if(!allowed) {
567  LOG("PythiaHad", pWARN)
568  << "Impossible interaction type / probe / hit quark combination!";
569  return false;
570  }
571 
572  return true;
573 }
574 //____________________________________________________________________________
575 /*
576 void PythiaHadronization::SwitchDecays(int pdgc, bool on_off) const
577 {
578  LOG("PythiaHad", pNOTICE)
579  << "Switching " << ((on_off) ? "ON" : "OFF")
580  << " all PYTHIA decay channels for particle = " << pdgc;
581 
582  int flag = (on_off) ? 1 : 0;
583  int kc = fPythia->Pycomp(pdgc);
584  int first_ch = fPythia->GetMDCY(kc,2);
585  int last_ch = fPythia->GetMDCY(kc,2) + fPythia->GetMDCY(kc,3) - 1;
586 
587  for(int ich = first_ch; ich < last_ch; ich++) fPythia->SetMDME(ich,1,flag);
588 }
589 */
590 //____________________________________________________________________________
591 /*
592 void PythiaHadronization::HandleDecays(TClonesArray * plist) const
593 {
594 // Handle decays of unstable particles if requested through the XML config.
595 // The default is not to decay the particles at this stage (during event
596 // generation, the UnstableParticleDecayer event record visitor decays what
597 // is needed to be decayed later on). But, when comparing various models
598 // (eg PYTHIA vs KNO) independently and not within the full MC simulation
599 // framework it might be necessary to force the decays at this point.
600 
601  if(!fDecayer) {
602  LOG("PythiaHad", pWARN) << "No decayer was specified!";
603  return;
604  }
605 
606  this->SwitchDecays(kPdgLambda, true); // decay Lambda
607  this->SwitchDecays(kPdgAntiLambda, true); // decay \bar{Lambda}
608  this->SwitchDecays(kPdgSigmaP, true); // decay Sigma+
609  this->SwitchDecays(kPdgSigma0, true); // decay Sigma0
610  this->SwitchDecays(kPdgSigmaM, true); // decay Sigma-
611  this->SwitchDecays(kPdgAntiSigmaP, true); // decay Sigma+
612  this->SwitchDecays(kPdgAntiSigma0, true); // decay Sigma0
613  this->SwitchDecays(kPdgAntiSigmaM, true); // decay Sigma-
614  this->SwitchDecays(kPdgXi0, true); // decay Xi0
615  this->SwitchDecays(kPdgXiM, true); // decay Xi-
616  this->SwitchDecays(kPdgAntiXi0, true); // decay \bar{Xi0}
617  this->SwitchDecays(kPdgAntiXiP, true); // decay \bar{Xi+}
618  this->SwitchDecays(kPdgOmegaM, true); // decay Omega-
619  this->SwitchDecays(kPdgAntiOmegaP, true); // decay \bar{Omega+}
620 
621  int mstj21 = fPythia->GetMSTJ(21);
622  fPythia->SetMSTJ(21,1);
623  fPythia->SetMSTJ(22,2);
624  fPythia->SetPARJ(71,100);
625 
626  //-- loop through the fragmentation event record & decay unstables
627  int idecaying = -1; // position of decaying particle
628  TMCParticle * p = 0; // current particle
629 
630  TIter piter(plist);
631  while ( (p = (TMCParticle *) piter.Next()) ) {
632  idecaying++;
633  int status = p->GetKS();
634  int pdg = p->GetKF();
635 
636  bool decay_it = (status<10) &&
637  ( pdg == kPdgLambda ||
638  pdg == kPdgAntiLambda ||
639  pdg == kPdgSigmaP ||
640  pdg == kPdgSigma0 ||
641  pdg == kPdgSigmaM ||
642  pdg == kPdgAntiSigmaP ||
643  pdg == kPdgAntiSigma0 ||
644  pdg == kPdgAntiSigmaM ||
645  pdg == kPdgXi0 ||
646  pdg == kPdgXiM ||
647  pdg == kPdgAntiXi0 ||
648  pdg == kPdgAntiXiP ||
649  pdg == kPdgOmegaM ||
650  pdg == kPdgAntiOmegaP );
651 
652  // bother for final state particle only
653  if(decay_it) {
654 
655  LOG("PythiaHad", pINFO)
656  << "Decaying particle with pdgc = " << p->GetKF();
657 
658  DecayerInputs_t dinp;
659 
660  TLorentzVector p4;
661  p4.SetPxPyPzE(p->GetPx(), p->GetPy(), p->GetPz(), p->GetEnergy());
662 
663  dinp.PdgCode = p->GetKF();
664  dinp.P4 = &p4;
665 
666  TClonesArray * decay_products = fDecayer->Decay(dinp);
667  if(decay_products) {
668  //-- mark the parent particle as decayed & set daughters
669  p->SetKS(11);
670 
671  int nfp = plist->GetEntries(); // n. fragm. products
672  int ndp = decay_products->GetEntries(); // n. decay products
673 
674  p->SetFirstChild ( nfp ); // decay products added at
675  p->SetLastChild ( nfp + ndp -1 ); // the end of the fragm.rec.
676 
677  //-- add decay products to the fragmentation record
678  TMCParticle * dp = 0;
679  TIter dpiter(decay_products);
680 
681  while ( (dp = (TMCParticle *) dpiter.Next()) ) {
682  if(dp->GetKS()>10) continue;
683  dp->SetParent(idecaying);
684  new ( (*plist)[plist->GetEntries()] ) TMCParticle(*dp);
685  }
686 
687  //-- clean up decay products
688  decay_products->Delete();
689  delete decay_products;
690  }
691 
692  } // KS < 10 : final state particle (as in PYTHIA LUJETS record)
693  } // particles in fragmentation record
694 
695  fPythia->SetMSTJ(21,mstj21); // restore mstj(21)
696 }
697 */
698 //____________________________________________________________________________
699 
const int kPdgP33m1232_DeltaPP
Definition: PDGCodes.h:91
double fRvnCCm3
neugen&#39;s Rijk: vn, CC, multiplicity = 3
PDGCodeList * SelectParticles(const Interaction *) const
const int kPdgUUDiquarkS1
Definition: PDGCodes.h:58
double W(bool selected=false) const
Definition: Kinematics.cxx:167
double fRvbpCCm3
neugen&#39;s Rijk: vbp, CC, multiplicity = 3
Basic constants.
double fSSBarSuppression
ssbar suppression
bool HitSeaQrk(void) const
Definition: Target.cxx:316
bool IsWeakCC(void) const
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:108
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:26
#define pERROR
Definition: Messenger.h:60
const int kPdgLambda
Definition: PDGCodes.h:69
double MaxMult(const Interaction *i) const
bool IsUQuark(int pdgc)
Definition: PDGUtils.cxx:249
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:79
int HitNucPdg(void) const
Definition: Target.cxx:321
double fLundaDiq
adjustment of Lund a for di-quark
double fRvnNCm2
neugen&#39;s Rijk: vn, NC, multiplicity = 2
double fRvbpCCm2
neugen&#39;s Rijk: vbp, CC, multiplicity = 2
double fDiQuarkSuppression
di-quark suppression parameter
int HitQrkPdg(void) const
Definition: Target.cxx:259
double fRvpCCm2
neugen&#39;s Rijk: vp, CC, multiplicity = 2
opt
Definition: train.py:196
const int kPdgUQuark
Definition: PDGCodes.h:42
Generated/set kinematical variables for an event.
Definition: Kinematics.h:40
const DecayModelI * fDecayer
bool IsDarkMatter(int pdgc)
Definition: PDGUtils.cxx:125
double fNonGaussianPt2Tail
non gaussian pt2 tail parameterization
bool IsSQuark(int pdgc)
Definition: PDGUtils.cxx:259
double fLundb
Lund b parameter.
void py2ent_(int *, int *, int *, double *)
bool IsAntiSQuark(int pdgc)
Definition: PDGUtils.cxx:279
double fRvbnNCm3
neugen&#39;s Rijk: vbn, NC, multiplicity = 3
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:274
virtual const Registry & GetConfig(void) const
Definition: Algorithm.cxx:254
A list of PDG codes.
Definition: PDGCodeList.h:33
const int kPdgP33m1232_DeltaP
Definition: PDGCodes.h:90
double fRvpNCm2
neugen&#39;s Rijk: vp, NC, multiplicity = 2
const int kPdgP33m1232_DeltaM
Definition: PDGCodes.h:88
const int kPdgK0
Definition: PDGCodes.h:151
bool IsCharmEvent(void) const
Definition: XclsTag.h:48
double W(const Interaction *const i)
Definition: KineUtils.cxx:1019
TH1D * CreateMultProbHist(double maxmult) const
double fLightVMesonSuppression
Light vector meon suppression.
bool IsNeutron(int pdgc)
Definition: PDGUtils.cxx:304
bool IsPosChargedLepton(int pdgc)
Definition: PDGUtils.cxx:140
Summary information for an interaction.
Definition: Interaction.h:55
const int kPdgAntiUQuark
Definition: PDGCodes.h:43
double fGaussianPt2
gaussian pt2 distribution width
Pure abstract base class. Defines the DecayModelI interface to be implemented by any algorithmic clas...
Definition: DecayModelI.h:31
bool IsProton(int pdgc)
Definition: PDGUtils.cxx:299
void Configure(const Registry &config)
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
double fRvpNCm3
neugen&#39;s Rijk: vp, NC, multiplicity = 3
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
bool IsDiQuark(int pdgc)
Definition: PDGUtils.cxx:223
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
virtual void Configure(const Registry &config)
Definition: Algorithm.cxx:70
int ProbePdg(void) const
Definition: InitialState.h:65
double fRvbnNCm2
neugen&#39;s Rijk: vbn, NC, multiplicity = 2
const int kPdgPi0
Definition: PDGCodes.h:137
const int kPdgDQuark
Definition: PDGCodes.h:44
double fLunda
Lund a parameter.
#define pINFO
Definition: Messenger.h:63
const int kPdgAntiK0
Definition: PDGCodes.h:152
const int kPdgUDDiquarkS0
Definition: PDGCodes.h:56
double fRvpCCm3
neugen&#39;s Rijk: vp, CC, multiplicity = 3
double fRvbpNCm2
neugen&#39;s Rijk: vbp, NC, multiplicity = 2
#define pWARN
Definition: Messenger.h:61
const int kPdgP33m1232_Delta0
Definition: PDGCodes.h:89
bool IsEM(void) const
double fRvnNCm3
neugen&#39;s Rijk: vn, NC, multiplicity = 3
double fSVMesonSuppression
Strange vector meson suppression.
void ApplyRijk(const Interaction *i, bool norm, TH1D *mp) const
TRandom3 & RndHadro(void) const
rnd number generator used by hadronization models
Definition: RandomGen.h:54
double Wmin(void) const
Various utility methods common to hadronization models.
double fRemainingECutoff
remaining E cutoff for stopping fragmentation
bool HitQrkIsSet(void) const
Definition: Target.cxx:309
An abstract class. It avoids implementing the HadronizationModelI interface, leaving it for the concr...
bool IsDarkMatter(void) const
TPythia6 * fPythia
PYTHIA6 wrapper class.
A registry. Provides the container for algorithm configuration parameters.
Definition: Registry.h:66
bool IsQuark(int pdgc)
Definition: PDGUtils.cxx:233
const XclsTag & ExclTag(void) const
Definition: Interaction.h:71
bool IsDQuark(int pdgc)
Definition: PDGUtils.cxx:254
TH1D * MultiplicityProb(const Interaction *, Option_t *opt="") const
void Print(const TClonesArray *const part_list)
double fWcut
configuration data common to all hadronizers
const InitialState & InitState(void) const
Definition: Interaction.h:68
const ProcessInfo & ProcInfo(void) const
Definition: Interaction.h:69
double fRvbnCCm3
neugen&#39;s Rijk: vbn, CC, multiplicity = 3
bool AssertValidity(const Interaction *i) const
weight
Definition: test.py:257
#define pNOTICE
Definition: Messenger.h:62
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
const Target & Tgt(void) const
Definition: InitialState.h:67
const int kPdgAntiLambda
Definition: PDGCodes.h:70
TClonesArray * Hadronize(const Interaction *) const
#define SLOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a short string (using the FUNCTION and...
Definition: Messenger.h:85
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:131
void push_back(int pdg_code)
Definition: PDGCodeList.cxx:67
double fRvbpNCm3
neugen&#39;s Rijk: vbp, NC, multiplicity = 3
bool IsAntiUQuark(int pdgc)
Definition: PDGUtils.cxx:269
double fRvnCCm2
neugen&#39;s Rijk: vn, CC, multiplicity = 2
Initial State information.
Definition: InitialState.h:49
#define pDEBUG
Definition: Messenger.h:64
double fRvbnCCm2
neugen&#39;s Rijk: vbn, CC, multiplicity = 2
const int kPdgDDDiquarkS1
Definition: PDGCodes.h:55
const Algorithm * SubAlg(const RgKey &registry_key) const
Definition: Algorithm.cxx:353