14#include <TClonesArray.h>
15#include <TLorentzVector.h>
16#include <TDecayChannel.h>
38Decayer(
"genie::Pythia8Decayer2023")
44Decayer(
"genie::Pythia8Decayer2023", config)
57 <<
"Running PYTHIA8 particle decayer "
61 TObjArrayIter piter(event);
70 int pdg_code = p->
Pdg();
74 if(!this->
ToBeDecayed(pdg_code, status_code))
continue;
77 <<
"Decaying unstable particle: " << p->
Name();
79 bool decayed = this->
Decay(ipos, event);
84 <<
"Done finding & decaying unstable particles";
91#ifdef __GENIE_PYTHIA8_ENABLED__
97 GHepParticle * decay_particle =
event->Particle(decay_particle_id);
98 if(!decay_particle)
return 0;
104 bool in_nucleus = (target_nucleus!=0);
107 TLorentzVector decay_particle_p4 = *(decay_particle->
P4());
108 TLorentzVector decay_particle_x4 = *(decay_particle->
X4());
109 int decay_particle_pdg_code = decay_particle->
Pdg();
114 gPythia->event.reset();
118 if ( !gPythia->particleData.findParticle(decay_particle_pdg_code) ) {
120 <<
" can NOT find pdgid = " << decay_particle_pdg_code
121 <<
" in Pythia8::ParticleData";
125 if ( !gPythia->particleData.canDecay(decay_particle_pdg_code) ) {
127 <<
" Particle of pdgid = " << decay_particle_pdg_code
128 <<
" can NOT be decayed by Pythia8";
134 gPythia->event.append( decay_particle_pdg_code, 1, 0, 0,
135 decay_particle_p4.Px(),
136 decay_particle_p4.Py(),
137 decay_particle_p4.Pz(),
138 decay_particle_p4.E(),
139 decay_particle_p4.M() );
149 double a = decay_particle_p4.Vect().Angle(polz);
150 gPythia->event.back().pol( round( std::cos(
a) ) );
152 int npart_before_decay = gPythia->event.size();
159 int npart_after_decay = gPythia->event.size();
161 LOG(
"Pythia8Decay",
pINFO) <<
"before " << npart_before_decay <<
" after " << npart_after_decay;
174 for (
int ip=npart_before_decay; ip<npart_after_decay; ++ip )
184 if ( gPythia->event[ip].status() < 0 )
continue;
186 Pythia8::Event &fEvent = gPythia->event;
188 int daughter_pdg_code = fEvent[ip].id();
190 int mother1 = decay_particle_id;
204 daughter_status_code,
213 fEvent[ip].xProd() * space_scale + decay_particle_x4.X(),
214 fEvent[ip].yProd() * space_scale + decay_particle_x4.Y(),
215 fEvent[ip].zProd() * space_scale + decay_particle_x4.Z(),
216 fEvent[ip].tProd() * time_scale + decay_particle_x4.T()
220 <<
"Adding daughter particle with PDG code = "
221 << daughter_pdg_code <<
", m = " << mcp.
Mass()
222 <<
" GeV, E = " << mcp.
Energy() <<
" GeV)";
224 event->AddParticle(mcp);
229 double weight =
event->Weight() *
fWeight;
230 event->SetWeight(weight);
238 <<
"calling GENIE/PYTHIA8 decay without enabling PYTHIA8";
249#ifdef __GENIE_PYTHIA8_ENABLED__
253 gPythia->readString(
"ProcessLevel:all = off");
254 gPythia->readString(
"ProcessLevel:resonanceDecays=on");
256 gPythia->readString(
"Print:quiet = on");
260 long int seed = rnd->
GetSeed();
261 gPythia->readString(
"Random::setSeed = on");
262 gPythia->settings.mode(
"Random:seed",seed);
264 <<
"PYTHIA8 seed = " << gPythia->settings.mode(
"Random:seed");
272 gPythia->readString(
"111:onMode = off");
276 <<
"calling GENIE/PYTHIA8 decay without enabling PYTHIA8";
289 <<
"Can decay particle with PDG code = " << pdg_code
290 <<
"? " << ((is_handled)?
"Yes" :
"No");
299#ifdef __GENIE_PYTHIA8_ENABLED__
302 bool known = gPythia->particleData.isParticle(pdg_code);
305 <<
"Can not switch off decays of " << pdg_code
306 <<
" as it is UNKNOWN to Pythia8";
310 auto pdentry = gPythia->particleData.particleDataEntryPtr(pdg_code);
313 int ilast_chan = pdentry->sizeChannels() - 1;
314 if (ilast_chan < 0) {
316 <<
"No available decay channels for " << pdg_code;
322 <<
"Switching off individual decay channels for particle = " << pdg_code
323 <<
" is NOT yet supported for Pythia8";
332 for (
int ichan=ifirst_chan; ichan<=ilast_chan; ++ichan) {
333 int onMode = pdentry->channel(ichan).onMode();
335 bool is_particle = (pdg_code>0);
341 onMode = (is_particle ? 3 : 2);
344 onMode = (is_particle ? 0 : 2);
347 onMode = (is_particle ? 3 : 0);
350 pdentry->channel(ichan).onMode(onMode);
359 <<
"calling GENIE/PYTHIA8 decay without enabling PYTHIA8";
370#ifdef __GENIE_PYTHIA8_ENABLED__
373 bool known = gPythia->particleData.isParticle(pdg_code);
376 <<
"Can not switch on decays of " << pdg_code
377 <<
" as it is UNKNOWN to Pythia8";
381 auto pdentry = gPythia->particleData.particleDataEntryPtr(pdg_code);
384 int ilast_chan = pdentry->sizeChannels() - 1;
385 if (ilast_chan < 0) {
387 <<
"No available decay channels for " << pdg_code;
393 <<
"Switching on individual decay channels for particle = " << pdg_code
394 <<
" is NOT yet supported for Pythia8";
403 for (
int ichan=ifirst_chan; ichan<=ilast_chan; ++ichan) {
404 int onMode = pdentry->channel(ichan).onMode();
406 bool is_particle = (pdg_code>0);
410 onMode = (is_particle ? 2 : 3);
415 onMode = (is_particle ? 2 : 0);
418 onMode = (is_particle ? 0 : 3);
421 pdentry->channel(ichan).onMode(onMode);
430 <<
"calling GENIE/PYTHIA8 decay without enabling PYTHIA8";
442#ifdef __GENIE_PYTHIA8_ENABLED__
445 <<
"Pythia8Decayer2023::SumOfBranchingRatios() not yet implemented";
449 LOG(
"Pythia8Decay",
pINFO) <<
"Sum{BR} = " << sumbr;
453 <<
"calling GENIE/PYTHIA8 decay without enabling PYTHIA8";
465#ifdef __GENIE_PYTHIA8_ENABLED__
468 <<
"Pythia8Decayer2023::FindPythiaDecayChannel() not yet implemented";
474 <<
"calling GENIE/PYTHIA8 decay without enabling PYTHIA8";
487#ifdef __GENIE_PYTHIA8_ENABLED__
490 <<
"Pythia8Decayer2023::MatchDecayChannels() not yet implemented";
496 <<
"calling GENIE/PYTHIA8 decay without enabling PYTHIA8";
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
#define SLOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a short string (using the FUNCTION and...
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
bool fRunBefHadroTransp
is invoked before or after FSI?
virtual bool ToBeDecayed(int pdgc, GHepStatus_t ist) const
STDHEP-like event record entry that can fit a particle or a nucleus.
string Name(void) const
Name that corresponds to the PDG code.
const TLorentzVector * P4(void) const
double Mass(void) const
Mass that corresponds to the PDG code.
const TLorentzVector * X4(void) const
void SetStatus(GHepStatus_t s)
double Energy(void) const
Get energy.
GHepStatus_t Status(void) const
void GetPolarization(TVector3 &polz)
GENIE's GHEP MC event record.
virtual ~Pythia8Decayer2023()
bool Decay(int ip, GHepRecord *event) const
void Initialize(void) const
void UnInhibitDecay(int pdgc, TDecayChannel *ch=0) const
void InhibitDecay(int pdgc, TDecayChannel *ch=0) const
void ProcessEventRecord(GHepRecord *event) const
int FindPythiaDecayChannel(int kc, TDecayChannel *ch) const
double SumOfBranchingRatios(int kc) const
bool MatchDecayChannels(int ic, TDecayChannel *ch) const
bool IsHandled(int pdgc) const
static Pythia8Singleton * Instance(void)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
static RandomGen * Instance()
Access instance.
long int GetSeed(void) const
static constexpr double m
static constexpr double mm
static constexpr double fm
static constexpr double s
bool IsBaryonResonance(int pdgc)
is input a baryon resonance?
THE MAIN GENIE PROJECT NAMESPACE
enum genie::EGHepStatus GHepStatus_t