9 #ifndef Pythia8_EvtGen_H 10 #define Pythia8_EvtGen_H 12 #include "Pythia8/Pythia.h" 13 #include "EvtGen/EvtGen.hh" 14 #include "EvtGenBase/EvtRandomEngine.hh" 15 #include "EvtGenBase/EvtParticle.hh" 16 #include "EvtGenBase/EvtParticleFactory.hh" 17 #include "EvtGenBase/EvtPDL.hh" 18 #include "EvtGenBase/EvtDecayTable.hh" 19 #include "EvtGenBase/EvtParticleDecayList.hh" 20 #include "EvtGenBase/EvtDecayBase.hh" 21 #include "EvtGenExternal/EvtExternalGenList.hh" 93 EvtExternalGenList *extPtrIn = 0, EvtAbsRadCorr *fsrPtrIn = 0,
94 int mixing = 1,
bool xml =
false,
bool limit =
true,
95 bool extUse =
true,
bool fsrUse =
true);
99 if (evtgen)
delete evtgen;
100 if (extOwner && extPtr)
delete extPtr;
101 if (fsrOwner && fsrPtr)
delete fsrPtr;
118 evtgen->readUDecay(decayFile.c_str(), xml); updateData();}
122 EvtExternalGenList *extPtr;
123 EvtAbsRadCorr *fsrPtr;
124 std::list<EvtDecayBase*> models;
127 struct Signal {
int status; EvtId egId; vector<double> bfs; vector<int> map;
128 EvtParticleDecayList modes;};
129 map<int, Signal> signals;
137 void updateData(
bool final =
false);
140 void updateEvent(
Particle *pyPro, EvtParticle *egPro,
141 vector<int> *pySigs = 0, vector<EvtParticle*> *egSigs = 0,
142 vector<double> *bfs = 0,
double *wgt = 0);
151 bool checkOsc(EvtParticle *egPro);
154 static const int NTRYDECAY = 1000;
176 bool limitTau0, limitTau, limitRadius, limitCylinder, limitDecay;
223 string particleDataFile, EvtExternalGenList *extPtrIn,
224 EvtAbsRadCorr *fsrPtrIn,
int mixing,
bool xml,
bool limit,
225 bool extUse,
bool fsrUse) : extPtr(extPtrIn), fsrPtr(fsrPtrIn),
226 signalSuffix(
"_SIGNAL"), pythiaPtr(pythiaPtrIn), rndm(&pythiaPtr->rndm),
230 if (!extPtr && fsrPtr) {
231 cout <<
"Error in EvtGenDecays::" 232 <<
"EvtGenDecays: extPtr is null but fsrPtr is provided\n";
236 else {
extOwner =
true; extPtr =
new EvtExternalGenList();}
237 if (fsrPtr) fsrOwner =
false;
238 else {fsrOwner =
true; fsrPtr = extPtr->getPhotosModel();}
239 models = extPtr->getListOfModels();
240 evtgen =
new EvtGen(decayFile.c_str(), particleDataFile.c_str(),
241 &
rndm, fsrUse ? fsrPtr : 0, extUse ? &models : 0, mixing, xml);
254 limitDecay = limit && (limitTau0 || limitTau ||
255 limitRadius || limitCylinder);
290 vector<int> pySigs; vector<EvtParticle*> egSigs, egPrts;
291 vector<double> bfs;
double wgt(1.);
292 for (
int iPro = 0; iPro <
event.size(); ++iPro) {
296 if (!pyPro->isFinal())
continue;
298 if (pyPro->status() == 93 || pyPro->status() == 94)
continue;
301 EvtParticle *egPro = EvtParticleFactory::particleFactory
302 (EvtPDL::evtIdFromStdHep(pyPro->
id()),
303 EvtVector4R(pyPro->e(), pyPro->px(), pyPro->py(), pyPro->pz()));
304 egPrts.push_back(egPro);
305 egPro->setDiagonalSpinDensity();
306 evtgen->generateDecay(egPro);
307 pyPro->tau(egPro->getLifetime());
312 updateEvent(pyPro, egPro, &pySigs, &egSigs, &bfs, &wgt);
316 pySigs.push_back(pyPro->
index());
317 egSigs.push_back(egPro);
318 bfs.push_back(
signal->second.bfs[0]);
319 wgt *= 1 - bfs.back();
320 egPro->deleteDaughters();
321 EvtParticle *egDau = EvtParticleFactory::particleFactory
322 (EvtPDL::evtIdFromStdHep(pyPro->
id()),
323 EvtVector4R(pyPro->e(), pyPro->px(), pyPro->py(), pyPro->pz()));
324 egDau->addDaug(egPro);
325 egDau->setDiagonalSpinDensity();
328 }
else updateEvent(pyPro, egPro, &pySigs, &egSigs, &bfs, &wgt);
330 if (pySigs.size() == 0) {
331 for (
int iPrt = 0; iPrt < (int)egPrts.size(); ++iPrt)
332 egPrts[iPrt]->deleteTree();
337 vector<int> modes;
int force(-1), n(0);
338 for (
int iTry = 1; iTry <=
NTRYDECAY; ++iTry) {
340 for (
int iSig = 0; iSig < (int)pySigs.size(); ++iSig) {
341 if (iSig == force) modes.push_back(0);
343 if (modes.back() == 0) ++n;
348 cout <<
"Warning in EvtGenDecays::decay: maximum " 349 <<
"number of signal decay attempts exceeded";
354 for (
int iSig = 0; iSig < (int)pySigs.size(); ++iSig) {
355 EvtParticle *egSig = egSigs[iSig];
356 Particle *pySig = &
event[pySigs[iSig]];
358 if (egSig->getNDaug() > 0) egSig = egSig->getDaug(0);
359 if (modes[iSig] == 0) egSig->setId(
signal->second.egId);
361 signal->second.modes.getDecayModel(egSig);
362 egSig->setChannel(
signal->second.map[egSig->getChannel()]);
365 pySig->status(pySig->status() == 92 || pySig->status() == 94 ? 96 : 95);
366 evtgen->generateDecay(egSig);
371 for (
int iPrt = 0; iPrt < (int)egPrts.size(); ++iPrt)
372 egPrts[iPrt]->deleteTree();
387 for (
int entry = 0; entry < (int)EvtPDL::entries(); ++entry) {
388 EvtId egId = EvtPDL::getEntry(entry);
389 int pyId = EvtPDL::getStdHep(egId);
412 EvtId egId = EvtPDL::evtIdFromStdHep(pyId);
437 EvtDecayTable *egTable = EvtDecayTable::getInstance();
438 if (!egTable)
return;
439 for (
int iEntry = 0; iEntry < (int)EvtPDL::entries(); ++iEntry) {
440 EvtId egId = EvtPDL::getEntry(iEntry);
441 int pyId = EvtPDL::getStdHep(egId);
442 if (egTable->getNModes(egId) == 0)
continue;
443 if (excIds.find(pyId) != excIds.end())
continue;
452 string egName = EvtPDL::name(egId);
453 if (egName.size() <=
signalSuffix.size() || egName.substr
455 signal = signals.find(pyId);
456 if (
signal == signals.end()) {
457 signals[pyId].status = -1;
458 signal = signals.find(pyId);
460 signal->second.egId = egId;
461 signal->second.bfs = vector<double>(2, 0);
462 if (!
final)
continue;
465 vector<EvtParticleDecayList> egList = egTable->getDecayTable();
466 int sigIdx = egId.getAlias();
467 int bkgIdx = EvtPDL::evtIdFromStdHep(pyId).getAlias();
468 if (sigIdx > (
int)egList.size() || bkgIdx > (int)egList.size())
continue;
469 EvtParticleDecayList sigModes = egList[sigIdx];
470 EvtParticleDecayList bkgModes = egList[bkgIdx];
471 EvtParticleDecayList allModes = egList[bkgIdx];
475 for (
int iMode = 0; iMode < sigModes.getNMode(); ++iMode) {
476 EvtDecayBase *mode = sigModes.getDecayModel(iMode);
478 signal->second.bfs[0] += mode->getBranchingFraction();
479 sum += mode->getBranchingFraction();
483 for (
int iMode = 0; iMode < allModes.getNMode(); ++iMode) {
484 EvtDecayBase *mode = allModes.getDecayModel(iMode);
487 for (
int jMode = 0; jMode < sigModes.getNMode(); ++jMode)
488 if (mode->matchingDecay(*(sigModes.getDecayModel(jMode)))) {
489 match =
true;
break;}
490 if (match) bkgModes.removeMode(mode);
492 signal->second.map.push_back(iMode);
493 signal->second.bfs[1] += mode->getBranchingFraction();
494 sum += mode->getBranchingFraction();
497 signal->second.modes = bkgModes;
498 for (
int iBf = 0; iBf < (int)
signal->second.bfs.size(); ++iBf)
499 signal->second.bfs[iBf] /= sum;
525 vector<int> *pySigs, vector<EvtParticle*> *egSigs,
526 vector<double> *bfs,
double *wgt) {
530 EvtParticle* egMom = egPro;
531 if (egPro->getNDaug() == 1 && egPro->getPDGId() ==
532 egPro->getDaug(0)->getPDGId()) egMom = egPro->getDaug(0);
534 vector< pair<EvtParticle*, int> >
535 moms(1, pair<EvtParticle*, int>(egMom, pyPro->
index()));
538 while (moms.size() != 0) {
541 egMom = moms.back().first;
542 int iMom = moms.back().second;
549 pyMom->daughters(event.size(),
event.size() + egMom->getNDaug() - 1);
551 Vec4 vProd = pyMom->vDec();
552 for (
int iDtr = 0 ; iDtr < (int)egMom->getNDaug(); ++iDtr) {
553 EvtParticle *egDtr = egMom->getDaug(iDtr);
554 int id = egDtr->getPDGId();
555 EvtVector4R p = egDtr->getP4Lab();
556 int idx =
event.append(
id, 93, iMom, 0, 0, 0, 0, 0, p.get(1),
557 p.get(2), p.get(3), p.get(0), egDtr->mass());
560 pyDtr->tau(egDtr->getLifetime());
561 if (pySigs && egSigs && bfs && wgt &&
checkSignal(pyDtr)) {
562 pySigs->push_back(pyDtr->
index());
563 egSigs->push_back(egDtr);
564 bfs->push_back(
signal->second.bfs[0]);
565 (*wgt) *= 1 - bfs->back();
566 egDtr->deleteDaughters();
568 if (osc) pyDtr->status(94);
569 if (egDtr->getNDaug() > 0)
570 moms.push_back(pair<EvtParticle*, int>(egDtr, idx));
583 if (!limitDecay)
return true;
584 if (limitTau0 && pyPro->tau0() >
tau0Max)
return false;
585 if (limitTau && pyPro->tau() > tauMax)
return false;
586 if (limitRadius &&
pow2(pyPro->xDec()) +
pow2(pyPro->yDec())
587 +
pow2(pyPro->zDec()) >
pow2(rMax))
return false;
588 if (limitCylinder && (
pow2(pyPro->xDec()) +
pow2(pyPro->yDec())
589 >
pow2(xyMax) || abs(pyPro->zDec()) > zMax) )
return false;
599 if (
signal != signals.end() && (
signal->second.status < 0 ||
600 signal->second.status == pyPro->status()))
return true;
612 if (egPro && egPro->getNDaug() == 1 &&
613 egPro->getPDGId() != egPro->getDaug(0)->getPDGId())
return true;
EvtGenRandom(Rndm *rndmPtrIn)
Constructor.
Definition: EvtGen.h:34
constexpr double pow2(const double &x)
Powers of small integers - for balance speed/code clarity.
Definition: PythiaStdlib.h:182
bool updated
Flag whether the final particle update has been performed.
Definition: EvtGen.h:169
Rndm * rndmPtr
The random number pointer.
Definition: EvtGen.h:40
double random()
Return a random number.
Definition: EvtGen.h:37
bool flag(string keyIn)
Give back current value, with check that key exists.
Definition: Settings.cc:1478
bool checkVertex(Particle *pyPro)
Check if a particle can decay.
Definition: EvtGen.h:582
Rndm rndm
Random number generator.
Definition: Pythia.h:338
ParticleData particleData
ParticleData: the particle data table/database.
Definition: Pythia.h:335
The Event class holds all info on the generated event.
Definition: Event.h:453
void readDecayFile(string decayFile, bool xml=false)
Read an EvtGen user decay file.
Definition: EvtGen.h:117
void updateEvtGen()
Update the EvtGen particle database from Pythia.
Definition: EvtGen.h:408
Settings settings
Settings: databases of flags/modes/parms/words to control run.
Definition: Pythia.h:332
void id(int idIn)
Member functions for input.
Definition: Event.h:88
Map of signal particle info.
Definition: EvtGen.h:127
Event event
The event record for the complete event history.
Definition: Pythia.h:323
~EvtGenDecays()
Destructor.
Definition: EvtGen.h:98
static const int NTRYDECAY
Number of times to try a decay sampling (constant).
Definition: EvtGen.h:154
Pythia * pythiaPtr
The pointer to the associated Pythia object.
Definition: EvtGen.h:157
void updateData(bool final=false)
Update the particles to decay with EvtGen, and the selected signals.
Definition: EvtGen.h:433
A class to wrap the Pythia random number generator for use by EvtGen.
Definition: EvtGen.h:29
EvtGen * evtgen
The EvtGen object.
Definition: EvtGen.h:163
EvtGenDecays(Pythia *pythiaPtrIn, string decayFile, string particleDataFile, EvtExternalGenList *extPtrIn=0, EvtAbsRadCorr *fsrPtrIn=0, int mixing=1, bool xml=false, bool limit=true, bool extUse=true, bool fsrUse=true)
Constructor.
Definition: EvtGen.h:222
map< int, Signal >::iterator signal
The selected signal iterator.
Definition: EvtGen.h:172
bool checkOsc(EvtParticle *egPro)
Check if an EvtGen particle has oscillated.
Definition: EvtGen.h:611
int nextId(int idIn) const
Return the id of the sequentially next particle stored in table.
Definition: ParticleData.cc:2230
double tau0Max
Parameters used to check if a particle should decay (as set via Pythia).
Definition: EvtGen.h:175
bool extOwner
External model pointer and FSR model pointer.
Definition: EvtGen.h:121
bool checkSignal(Particle *pyPro)
Check if a particle is signal.
Definition: EvtGen.h:597
double decay()
Perform all decays and return the event weight.
Definition: EvtGen.h:282
void updateEvent(Particle *pyPro, EvtParticle *egPro, vector< int > *pySigs=0, vector< EvtParticle * > *egSigs=0, vector< double > *bfs=0, double *wgt=0)
Update the Pythia event record with an EvtGen decay tree.
Definition: EvtGen.h:524
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20
EvtGenRandom rndm
Random number wrapper for EvtGen.
Definition: EvtGen.h:160
The Pythia class contains the top-level routines to generate an event.
Definition: Pythia.h:71
double flat()
Generate next random number uniformly between 0 and 1.
Definition: Basics.cc:189
string signalSuffix
The suffix indicating an EvtGen particle or alias is signal.
Definition: EvtGen.h:132
set< int > incIds
Set of particle IDs to include and exclude decays with EvtGen.
Definition: EvtGen.h:166
void updatePythia()
Update the Pythia particle database from EvtGen.
Definition: EvtGen.h:385
void exclude(int id)
Stop EvtGen decaying a particle.
Definition: EvtGen.h:108
int pick(const vector< double > &prob)
Pick one option among vector of (positive) probabilities.
Definition: Basics.cc:103
virtual int index() const
Methods that can refer back to the event the particle belongs to.
Definition: Event.cc:87