14#include <generators/utilities/GeneratorConst.h>
15#include "Pythia8/Pythia.h"
16#include "EvtGen/EvtGen.hh"
17#include "EvtGenBase/EvtRandomEngine.hh"
18#include "EvtGenBase/EvtParticle.hh"
19#include "EvtGenBase/EvtParticleFactory.hh"
20#include "EvtGenBase/EvtPDL.hh"
21#include "EvtGenBase/EvtDecayTable.hh"
22#include "EvtGenBase/EvtParticleDecayList.hh"
23#include "EvtGenBase/EvtDecayBase.hh"
24#include "EvtGenExternal/EvtExternalGenList.hh"
93 EvtGenDecays(Pythia8::Pythia* pythiaPtrIn, EvtGen* evtGen,
bool limit =
true);
96 EvtGenDecays(Pythia8::Pythia* pythiaPtrIn, std::string decayFile, std::string particleDataFile,
97 EvtExternalGenList* extPtrIn = 0, EvtAbsRadCorr* fsrPtrIn = 0,
98 int mixing = 1,
bool xml =
false,
bool limit =
true,
99 bool extUse =
true,
bool fsrUse =
true);
162 void updateEvent(Pythia8::Particle* pyPro, EvtParticle* egPro,
163 std::vector<int>* pySigs = 0, std::vector<EvtParticle*>* egSigs = 0,
164 std::vector<double>* bfs = 0,
double* wgt = 0);
256 extOwner(false), fsrOwner(false), extPtr(nullptr), fsrPtr(nullptr),
257 signalSuffix(
"_SIGNAL"), pythiaPtr(pythiaPtrIn), rndm(nullptr),
258 evtgen(evtGen), updated(false)
264 std::string particleDataFile, EvtExternalGenList* extPtrIn,
265 EvtAbsRadCorr* fsrPtrIn,
int mixing,
bool xml,
bool limit,
266 bool extUse,
bool fsrUse) : extPtr(extPtrIn), fsrPtr(fsrPtrIn),
267 signalSuffix(
"_SIGNAL"), pythiaPtr(pythiaPtrIn), rndm(&pythiaPtr->rndm),
273 B2ERROR(
"Error in EvtGenDecays::EvtGenDecays: extPtr is null but fsrPtr is provided");
281 evtgen =
new EvtGen(decayFile.c_str(), particleDataFile.c_str(),
335 Pythia8::Event&
event =
pythiaPtr->event;
336 std::vector<int> pySigs; std::vector<EvtParticle*> egSigs, egPrts;
337 std::vector<double> bfs;
double wgt(1.);
338 for (
int iPro = 0; iPro <
event.size(); ++iPro) {
341 Pythia8::Particle* pyPro = &
event[iPro];
342 if (!pyPro->isFinal())
continue;
344 if (pyPro->status() == 93 || pyPro->status() == 94)
continue;
347 EvtParticle* egPro = EvtParticleFactory::particleFactory
348 (EvtPDL::evtIdFromStdHep(pyPro->id()),
349 EvtVector4R(pyPro->e(), pyPro->px(), pyPro->py(), pyPro->pz()));
350 egPrts.push_back(egPro);
351 egPro->setDiagonalSpinDensity();
352 evtgen->generateDecay(egPro);
353 pyPro->tau(egPro->getLifetime());
358 updateEvent(pyPro, egPro, &pySigs, &egSigs, &bfs, &wgt);
362 pySigs.push_back(pyPro->index());
363 egSigs.push_back(egPro);
364 bfs.push_back(
signal->second.bfs[0]);
365 wgt *= 1 - bfs.back();
366 egPro->deleteDaughters();
372 }
else updateEvent(pyPro, egPro, &pySigs, &egSigs, &bfs, &wgt);
374 if (pySigs.size() == 0) {
375 for (
int iPrt = 0; iPrt < (int)egPrts.size(); ++iPrt)
376 egPrts[iPrt]->deleteTree();
381 std::vector<int> modes;
int force(-1);
382 for (
int iTry = 1; iTry <=
NTRYDECAY; ++iTry) {
385 modes.clear(); force =
pythiaPtr->rndm.pick(bfs); n = 0;
386 for (
int iSig = 0; iSig < (int)pySigs.size(); ++iSig) {
387 if (iSig == force) modes.push_back(0);
388 else modes.push_back(
pythiaPtr->rndm.flat() > bfs[iSig]);
389 if (modes.back() == 0) ++n;
391 if (
pythiaPtr->rndm.flat() <= 1.0 / n)
break;
394 B2WARNING(
"Warning in EvtGenDecays::decay: maximum number of signal decay attempts exceeded"
400 for (
int iSig = 0; iSig < (int)pySigs.size(); ++iSig) {
401 EvtParticle* egSig = egSigs[iSig];
402 Pythia8::Particle* pySig = &
event[pySigs[iSig]];
404 if (egSig->getNDaug() > 0) egSig = egSig->getDaug(0);
405 if (modes[iSig] == 0) egSig->setId(
signal->second.egId);
407 signal->second.modes.getDecayModel(egSig);
408 egSig->setChannel(
signal->second.map[egSig->getChannel()]);
411 pySig->status(pySig->status() == 92 || pySig->status() == 94 ? 96 : 95);
412 evtgen->generateDecay(egSig);
417 for (
int iPrt = 0; iPrt < (int)egPrts.size(); ++iPrt)
418 egPrts[iPrt]->deleteTree();
434 for (
int entry = 0; entry < (int)EvtPDL::entries(); ++entry) {
435 EvtId egId = EvtPDL::getEntry(entry);
436 int pyId = EvtPDL::getStdHep(egId);
437 pythiaPtr->particleData.spinType(pyId, EvtPDL::getSpinType(egId));
438 pythiaPtr->particleData.chargeType(pyId, EvtPDL::chg3(egId));
439 pythiaPtr->particleData.m0(pyId, EvtPDL::getMass(egId));
440 pythiaPtr->particleData.mWidth(pyId, EvtPDL::getWidth(egId));
441 pythiaPtr->particleData.mMin(pyId, EvtPDL::getMinMass(egId));
442 pythiaPtr->particleData.mMax(pyId, EvtPDL::getMaxMass(egId));
443 pythiaPtr->particleData.tau0(pyId, EvtPDL::getctau(egId));
458 int pyId =
pythiaPtr->particleData.nextId(0);
460 EvtId egId = EvtPDL::evtIdFromStdHep(pyId);
461 EvtPDL::reSetMass(egId,
pythiaPtr->particleData.m0(pyId));
462 EvtPDL::reSetWidth(egId,
pythiaPtr->particleData.mWidth(pyId));
463 EvtPDL::reSetMassMin(egId,
pythiaPtr->particleData.mMin(pyId));
464 EvtPDL::reSetMassMax(egId,
pythiaPtr->particleData.mMax(pyId));
465 pyId =
pythiaPtr->particleData.nextId(pyId);
486 EvtDecayTable* egTable = EvtDecayTable::getInstance();
487 if (!egTable)
return;
488 for (
int iEntry = 0; iEntry < (int)EvtPDL::entries(); ++iEntry) {
489 EvtId egId = EvtPDL::getEntry(iEntry);
490 int pyId = EvtPDL::getStdHep(egId);
491 if (egTable->getNModes(egId) == 0)
continue;
497 pythiaPtr->particleData.mayDecay(pyId,
false);
501 std::string egName = EvtPDL::name(egId);
502 if (egName.size() <=
signalSuffix.size() || egName.substr
509 signal->second.egId = egId;
510 signal->second.bfs = std::vector<double>(2, 0);
511 if (!
final)
continue;
514 std::vector<EvtParticleDecayList> egList = egTable->getDecayTable();
515 int sigIdx = egId.getAlias();
516 int bkgIdx = EvtPDL::evtIdFromStdHep(pyId).getAlias();
517 if (sigIdx > (
int)egList.size() || bkgIdx > (
int)egList.size())
continue;
518 EvtParticleDecayList sigModes = egList[sigIdx];
519 EvtParticleDecayList bkgModes = egList[bkgIdx];
520 EvtParticleDecayList allModes = egList[bkgIdx];
524 for (
int iMode = 0; iMode < sigModes.getNMode(); ++iMode) {
525 EvtDecayBase* mode = sigModes.getDecayModel(iMode);
527 signal->second.bfs[0] += mode->getBranchingFraction();
528 sum += mode->getBranchingFraction();
532 for (
int iMode = 0; iMode < allModes.getNMode(); ++iMode) {
533 EvtDecayBase* mode = allModes.getDecayModel(iMode);
536 for (
int jMode = 0; jMode < sigModes.getNMode(); ++jMode)
537 if (mode->matchingDecay(*(sigModes.getDecayModel(jMode)))) {
540 if (match) bkgModes.removeMode(mode);
542 signal->second.map.push_back(iMode);
543 signal->second.bfs[1] += mode->getBranchingFraction();
544 sum += mode->getBranchingFraction();
547 signal->second.modes = bkgModes;
548 for (
int iBf = 0; iBf < (int)
signal->second.bfs.size(); ++iBf)
549 signal->second.bfs[iBf] /= sum;
575 std::vector<int>* pySigs, std::vector<EvtParticle*>* egSigs,
576 std::vector<double>* bfs,
double* wgt)
581 EvtParticle* egMom = egPro;
582 if (egPro->getNDaug() == 1 && egPro->getPDGId() ==
583 egPro->getDaug(0)->getPDGId()) egMom = egPro->getDaug(0);
584 Pythia8::Event&
event =
pythiaPtr->event;
585 std::vector< std::pair<EvtParticle*, int> >
586 moms(1, std::pair<EvtParticle*, int>(egMom, pyPro->index()));
589 while (moms.size() != 0) {
592 egMom = moms.back().first;
593 int iMom = moms.back().second;
594 Pythia8::Particle* pyMom = &
event[iMom];
600 pyMom->daughters(event.size(), event.size() + egMom->getNDaug() - 1);
602 Pythia8::Vec4 vProd = pyMom->vDec();
603 for (
int iDtr = 0 ; iDtr < (int)egMom->getNDaug(); ++iDtr) {
604 EvtParticle* egDtr = egMom->getDaug(iDtr);
605 int id = egDtr->getPDGId();
606 EvtVector4R p = egDtr->getP4Lab();
607 int idx =
event.append(
id, 93, iMom, 0, 0, 0, 0, 0, p.get(1),
608 p.get(2), p.get(3), p.get(0), egDtr->mass());
609 Pythia8::Particle* pyDtr = &
event.back();
611 pyDtr->tau(egDtr->getLifetime());
612 if (pySigs && egSigs && bfs && wgt &&
checkSignal(pyDtr)) {
613 pySigs->push_back(pyDtr->index());
614 egSigs->push_back(egDtr);
615 bfs->push_back(
signal->second.bfs[0]);
616 (*wgt) *= 1 - bfs->back();
617 egDtr->deleteDaughters();
619 if (osc) pyDtr->status(94);
620 if (egDtr->getAttribute(
"FSR"))
621 pyDtr->status(Belle2::GeneratorConst::FSR_STATUS_CODE);
622 if (egDtr->getNDaug() > 0)
623 moms.push_back(std::pair<EvtParticle*, int>(egDtr, idx));
637 using ::Pythia8::pow2;
642 if (
limitRadius && pow2(pyPro->xDec()) + pow2(pyPro->yDec())
643 + pow2(pyPro->zDec()) > pow2(
rMax))
return false;
644 if (
limitCylinder && (pow2(pyPro->xDec()) + pow2(pyPro->yDec())
645 > pow2(
xyMax) || abs(pyPro->zDec()) >
zMax))
return false;
657 signal->second.status == pyPro->status()))
return true;
670 if (egPro && egPro->getNDaug() == 1 &&
671 egPro->getPDGId() != egPro->getDaug(0)->getPDGId())
return true;
A class to perform decays via the external EvtGen decay program, see http://evtgen....
EvtGen * evtgen
The EvtGen object.
void updateData(bool final=false)
Update the particles to decay with EvtGen, and the selected signals.
EvtAbsRadCorr * fsrPtr
FSR model pointer.
void exclude(int id)
Stop EvtGen decaying a particle.
double tauMax
the pythia parameter ParticleDecays:tauMax
bool limitCylinder
the pythia parameter ParticleDecays:limitCylinder
~EvtGenDecays()
Destructor.
EvtGenDecays(Pythia8::Pythia *pythiaPtrIn, EvtGen *evtGen, bool limit=true)
Expert constructor which takes an already initialized EvtGen instance.
bool fsrOwner
bool has FSR model
std::map< int, Signal > signals
signal particles and statuses
std::set< int > incIds
Set of particle IDs to include decays with EvtGen.
std::list< EvtDecayBase * > models
list of model pointers
bool checkSignal(Pythia8::Particle *pyPro)
Check if a particle is signal.
bool updated
Flag whether the final particle update has been performed.
EvtGenDecays(const EvtGenDecays &)=delete
forbid copy
EvtExternalGenList * extPtr
External model pointer.
bool checkVertex(Pythia8::Particle *pyPro)
Check if a particle can decay.
double zMax
the pythia parameter ParticleDecays:zMax
void updatePythia()
Update the Pythia particle database from EvtGen.
bool checkOsc(EvtParticle *egPro)
Check if an EvtGen particle has oscillated.
double xyMax
the pythia parameter ParticleDecays:xyMax
std::set< int > excIds
Set of particle IDs to exclude decays with EvtGen.
bool limitTau
the pythia parameter ParticleDecays:limitTau
double rMax
the pythia parameter ParticleDecays:rMax
static constexpr int NTRYDECAY
Number of times to try a decay sampling (constant).
void updateEvtGen()
Update the EvtGen particle database from Pythia.
bool limitRadius
the pythia parameter ParticleDecays:limitRadius
bool limitDecay
is the decay limited
void readDecayFile(std::string decayFile, bool xml=false)
Read an EvtGen user decay file.
bool extOwner
bool has external model
void getDecayLimits(bool limit)
Get the Decay limits from Pythia.
std::string signalSuffix
The suffix indicating an EvtGen particle or alias is signal.
EvtGenDecays & operator=(const EvtGenDecays &)=delete
forbid assignment
void updateEvent(Pythia8::Particle *pyPro, EvtParticle *egPro, std::vector< int > *pySigs=0, std::vector< EvtParticle * > *egSigs=0, std::vector< double > *bfs=0, double *wgt=0)
Update the Pythia event record with an EvtGen decay tree.
EvtGenRandom rndm
Random number wrapper for EvtGen.
double decay()
Perform all decays and return the event weight.
bool limitTau0
the pythia parameter ParticleDecays:limitTau0
Pythia8::Pythia * pythiaPtr
The pointer to the associated Pythia object.
double tau0Max
Parameters used to check if a particle should decay (as set via Pythia).
std::map< int, Signal >::iterator signal
The selected signal iterator.
A class to wrap the Pythia random number generator for use by EvtGen.
double random()
Return a random number.
EvtGenRandom(Pythia8::Rndm *rndmPtrIn)
Constructor.
Pythia8::Rndm * rndmPtr
The random number pointer.
Class to store variables with their name which were sent to the logging service.
Map of signal particle info.
std::vector< int > map
the map for statuses
int status
status needed to consider a particle a signal
EvtParticleDecayList modes
list of decay modes &
std::vector< double > bfs
branching fractions