19#include "EvtGenBase/EvtAbsRadCorr.hh"
20#include "EvtGenBase/EvtDecayBase.hh"
21#include "EvtGen_i/EvtGenExternal/EvtExternalGenList.hh"
23#include "EvtGenBase/EvtVector4R.hh"
24#include "EvtGenBase/EvtParticle.hh"
25#include "EvtGenBase/EvtParticleFactory.hh"
26#include "EvtGen/EvtGen.hh"
27#include "EvtGenBase/EvtRandomEngine.hh"
28#include "EvtGenBase/EvtDecayTable.hh"
38#include "GaudiKernel/MsgStream.h"
39#include "GaudiKernel/ISvcLocator.h"
40#include "GaudiKernel/DataSvc.h"
41#include "GaudiKernel/IPartPropSvc.h"
45#include "HepPID/ParticleName.hh"
48#include "CLHEP/Random/RandFlat.h"
49#include "CLHEP/Vector/LorentzVector.h"
125 msg(MSG::INFO) <<
"EvtInclusiveDecay initialize" <<
endmsg;
130 msg(MSG::INFO) <<
"EvtInclusiveDecay selection parameters:" <<
endmsg;
137 msg(MSG::INFO) <<
"User selection parameters:" <<
endmsg;
149 msg(MSG::INFO) <<
"* blackList; = ";
151 msg(MSG::INFO) << (*i) <<
" ";
156 msg(MSG::INFO) <<
"* whiteList = ";
158 msg(MSG::INFO) << (*i) <<
" ";
166 EvtExternalGenList genList(
true,
xmlpath(),
"gamma");
167 EvtAbsRadCorr* radCorrEngine = genList.getPhotosModel();
168 std::list<EvtDecayBase*> extraModels = genList.getListOfModels();
179 return StatusCode::SUCCESS;
184 const EventContext& ctx)
193 const EventContext& ctx)
const
196 rngWrapper->
setSeed( streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
206 ctx.setEventID (EventIDBase (conditionsRun,
207 EventIDBase::UNDEFEVT,
208 EventIDBase::UNDEFNUM,
209 EventIDBase::UNDEFNUM,
221 const EventContext& ctx = Gaudi::Hive::currentContext();
245 HepMC::GenEvent* hepMC = *mcItr;
250 std::set<HepMC::GenVertexPtr> visited;
251 std::set<HepMC::GenParticlePtr,ParticleIdCompare> toBeDecayed;
252 for (
auto p: *hepMC) {
253 if ( (!p->production_vertex()) ||
254 (p->production_vertex()->particles_in_size() == 0) ) {
257 return StatusCode::FAILURE;
262 msg(MSG::INFO) <<
"Printing HepMC record at " << hepMC <<
" BEFORE running EvtGen:" <<
endmsg;
271 bool eventPassesCuts(
false);
275 for (
auto p: toBeDecayed) {
278 msg(MSG::ERROR ) <<
"Overlapping decay tree for particle" << p <<
endmsg;
282 return StatusCode::FAILURE;
291 eventPassesCuts =
true;
301 hepMC->weight(
"nEvtGenDecayAttempts") = loopCounter;
303 hepMC->weights()[
"nEvtGenDecayAttempts"] = loopCounter;
308 msg(MSG::INFO) <<
"Printing HepMC record at " << hepMC <<
" AFTER running EvtGen:" <<
endmsg;
320 return StatusCode::SUCCESS;
327 ATH_MSG_INFO(
"The following particles were checked and didn't have any decay channels:");
329 std::cout << std::endl;
330 std::cout <<
" Particle code Name from HepPDT # Occurences" << std::endl;
331 std::cout <<
"------------------------------------------------------" << std::endl;
334 int count = p->second;
335 std::cout << std::setw(14) <<
id
336 << std::setw(20) << HepPID::particleName(
id)
337 << std::setw(20) <<
count
340 std::cout << std::endl;
345 return StatusCode::SUCCESS;
359 std::set<HepMC::GenVertexPtr>& visited,
360 std::set<HepMC::GenParticlePtr,ParticleIdCompare>& toBeDecayed) {
362 if (!isToBeRemoved) {
364 toBeDecayed.insert(p);
365 isToBeRemoved =
true;
375 auto v = p->end_vertex();
377 if (visited.insert(v).second) {
379 ATH_MSG_WARNING(
"Found particle to be decayed with vertex with >1 incoming mother particles in decay tree");
388 return StatusCode::SUCCESS;
397 auto v = p->end_vertex();
401 hepMC->remove_vertex(std::move(v));
405 std::set<int> vtxBarCodesToDelete;
406 vtxBarCodesToDelete.insert(v->barcode());
407 for (HepMC::GenVertex::vertex_iterator itv = v->vertices_begin(HepMC::descendants);
408 itv != v->vertices_end(HepMC::descendants);
410 vtxBarCodesToDelete.insert((*itv)->barcode());
411 for (std::set<int>::iterator itb = vtxBarCodesToDelete.begin(); itb != vtxBarCodesToDelete.end(); ++itb) {
412 auto vdel = hepMC->barcode_to_vertex(*itb);
413 hepMC->remove_vertex(vdel);
417 ATH_MSG_DEBUG(
"Removed existing " <<
pdgName(p) <<
" (barcode " << p->barcode() <<
")" <<
" decay tree with " << vtxBarCodesToDelete.size() <<
" vertices");
449 int id = part->pdg_id();
450 EvtId evtId=EvtPDL::evtIdFromStdHep(
id);
451 double en =(part->momentum()).e()/1000.;
452 double px=(part->momentum()).px()/1000.;
453 double py=(part->momentum()).py()/1000.;
454 double pz=(part->momentum()).pz()/1000.;
455 EvtVector4R evtP(en,px,py,pz);
456 EvtParticle* evtPart = EvtParticleFactory::particleFactory(evtId,evtP);
459 if(
m_setVMtransversePol && (
id==113 ||
id== 443 ||
id==100443 ||
id==553 ||
id==100553 ||
id==200553) )evtPart->setVectorSpinDensity();
462 if (
msgLvl(MSG::VERBOSE)) evtPart->printTree();
463 double ct_s = part->production_vertex()->position().t();
464 double x_s = part->production_vertex()->position().x();
465 double y_s = part->production_vertex()->position().y();
466 double z_s = part->production_vertex()->position().z();
468 EvtVector4R treeStart(ct_s,x_s,y_s,z_s);
471 if(evtPart->getNDaug() !=0) part->set_status(2);
472 evtPart->deleteTree();
478 EvtParticle* evtPart, EvtVector4R treeStart,
double momentumScaleFactor) {
479 if(evtPart->getNDaug()!=0) {
481 double ct=(evtPart->getDaug(0)->get4Pos()).get(0)+treeStart.get(0);
482 double x=(evtPart->getDaug(0)->get4Pos()).get(1)+treeStart.get(1);
483 double y=(evtPart->getDaug(0)->get4Pos()).get(2)+treeStart.get(2);
484 double z=(evtPart->getDaug(0)->get4Pos()).get(3)+treeStart.get(3);
488 hepMC->add_vertex(end_vtx);
489 end_vtx->add_particle_in(std::move(part));
492 for(
uint it=0; it<evtPart->getNDaug(); it++) {
493 double e=(evtPart->getDaug(it)->getP4Lab()).get(0) * momentumScaleFactor;
494 double px=(evtPart->getDaug(it)->getP4Lab()).get(1) * momentumScaleFactor;
495 double py=(evtPart->getDaug(it)->getP4Lab()).get(2) * momentumScaleFactor;
496 double pz=(evtPart->getDaug(it)->getP4Lab()).get(3) * momentumScaleFactor;
497 int id=EvtPDL::getStdHep(evtPart->getDaug(it)->getId());
499 if(evtPart->getDaug(it)->getNDaug() != 0) status=2;
501 end_vtx->add_particle_out(daughter);
502 addEvtGenDecayTree(hepMC, std::move(daughter), evtPart->getDaug(it), treeStart, momentumScaleFactor);
516 int id = p->pdg_id();
518 auto v = p->end_vertex();
519 if (v) nDaughters = v->particles_out_size();
522 if (p->status() == 3)
return false;
528 double m2 = p->momentum().m2();
535 EvtId evtId = EvtPDL::evtIdFromStdHep(
id);
538 if (evtId.getId()>=0)
540 nModes = EvtDecayTable::getInstance()->getNMode(evtId.getAlias());
543 <<
" (status = " << p->status()
544 <<
") -- " << nModes <<
" decay modes found");
562 if (std::abs(itd->pdg_id()) == std::abs(
id))
return false;
585 int id = std::abs(pId);
608 std::vector<HepMC::GenParticlePtr> *muons =
new std::vector<HepMC::GenParticlePtr>;
610 for (
const auto& p: *hepMC) {
611 if( std::abs(p->pdg_id()) == 13 )
615 for (
auto muItr1 = muons->begin(); muItr1 != muons->end(); ++muItr1) {
616 for (
auto muItr2 = muItr1+1; muItr2 != muons->end(); ++muItr2) {
624 double dimuMass =
invMass((*muItr1),(*muItr2));
637 double p1Px = p1->momentum().px();
638 double p1Py = p1->momentum().py();
639 double p1Pz = p1->momentum().pz();
640 double p1E = p1->momentum().e();
641 double p2Px = p2->momentum().px();
642 double p2Py = p2->momentum().py();
643 double p2Pz = p2->momentum().pz();
644 double p2E = p2->momentum().e();
645 double dimuE = p2E + p1E;
646 double dimuPx = p2Px + p1Px;
647 double dimuPy = p2Py + p1Py;
648 double dimuPz = p2Pz + p1Pz;
649 double invMass = std::sqrt(dimuE*dimuE - dimuPx*dimuPx - dimuPy*dimuPy - dimuPz*dimuPz);
661 std::set<HepMC::GenVertexPtr> visited;
662 unsigned int nParticlesFound = 0;
663 unsigned int nTreesFound = 0;
664 for (
auto p: *hepMC) {
665 if ( (!p->production_vertex()) ||
666 (p->production_vertex()->particles_in_size() == 0) ) {
668 std::cout <<
"\n Found new partial decay tree:\n" << std::endl;
669 unsigned int nParticlesVisited =
printTree(std::move(p),visited,1,particleSet);
670 std::cout <<
"\n " << nParticlesVisited <<
" particles in this subtree" << std::endl;
671 nParticlesFound += nParticlesVisited;
674 std::cout <<
"\n Total of " << nParticlesFound <<
" particles found in "
675 << nTreesFound <<
" decay subtrees in HepMC event record\n" << std::endl;
680 unsigned int nParticlesVisited = 1;
681 for (
int i=0; i<level; i++) std::cout <<
" ";
683 auto v = p->end_vertex();
685 if (v->particles_in_size() > 1)
686 std::cout <<
" [interaction: " << v->particles_in_size() <<
" particles, vertex " << v <<
"] --> ";
688 std::cout <<
" --> ";
689 if (visited.insert(v).second) {
693 std::cout << std::endl;
695 if (itp->end_vertex())
696 nParticlesVisited +=
printTree(std::move(itp), visited, level+1, particleSet);
701 std::cout <<
"see above" << std::endl;
703 std::cout <<
" no decay vertex\n" << std::endl;
704 return nParticlesVisited;
708 std::ostringstream buf;
711 if (particleSet)
for (
const auto& pinl: *particleSet)
if (pinl&&p)
if (pinl.get() == p.get()) inlist=
true;
714 if (particleSet) inlist = (particleSet->find(p_nc) != particleSet->end());
716 if (statusHighlighting) {
717 if ( ((particleSet!=0) && (inlist)) ||
728 buf <<
"/" << HepPID::particleName(p->pdg_id());
729 if (statusHighlighting) {
744 return CLHEP::RandFlat::shoot(
m_engine);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define CHECK(...)
Evaluate an expression and check for errors.
defines an "iterator" over instances of a given type in StoreGateSvc
ATLAS-specific HepMC functions.
std::string PathResolverFindCalibDirectory(const std::string &logical_file_name)
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
A wrapper class for event-slot-local random engines.
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::iterator< DataVector > iterator
EvtInclusiveAtRndmGen(CLHEP::HepRandomEngine *engine)
CLHEP::HepRandomEngine * m_engine
bool m_applyUserSelection
void printHepMC(HepMC::GenEvent *hepMC, std::set< HepMC::GenParticlePtr, ParticleIdCompare > *particleSet=nullptr)
CLHEP::HepRandomEngine * getRandomEngine(const std::string &streamName, unsigned long int randomSeedOffset, const EventContext &ctx) const
bool m_setVMtransversePol
ServiceHandle< IAthRNGSvc > m_rndmSvc
double m_userSelMu1MaxEta
void removeDecayTree(HepMC::GenEvent *hepMC, HepMC::GenParticlePtr p)
bool m_userSelRequireOppositeSignedMu
void reseedRandomEngine(const std::string &streamName, const EventContext &ctx)
virtual ~EvtInclusiveDecay()
bool isDefaultB(const int pId) const
std::set< int > m_blackListSet
CLHEP::HepRandomEngine * getRandomEngineDuringInitialize(const std::string &streamName, unsigned long int randomSeedOffset, unsigned int conditionsRun=1, unsigned int lbn=1) const
bool m_printHepMCAfterEvtGen
bool m_checkDecayChannels
void addEvtGenDecayTree(HepMC::GenEvent *hepMC, HepMC::GenParticlePtr part, EvtParticle *evtPart, EvtVector4R treeStart, double momentumScaleFactor=1.0)
std::string m_randomStreamName
double m_userSelMaxDimuMass
StatusCode traverseDecayTree(HepMC::GenParticlePtr p, bool isToBeRemoved, std::set< HepMC::GenVertexPtr > &visited, std::set< HepMC::GenParticlePtr, ParticleIdCompare > &toBeDecayed)
bool passesUserSelection(HepMC::GenEvent *hepMC)
double m_userSelMinDimuMass
bool m_printHepMCBeforeEvtGen
double invMass(HepMC::ConstGenParticlePtr p1, HepMC::ConstGenParticlePtr p2)
McEventCollection * m_mcEvtColl
bool m_allowDefaultBDecays
std::string m_userDecayFile
std::string xmlpath(void)
std::set< int > m_whiteListSet
double m_userSelMu2MaxEta
IntegerProperty m_randomSeed
Seed for random number engine.
std::vector< int > m_blackList
bool m_prohibitRemoveSelfDecay
unsigned int printTree(HepMC::GenParticlePtr p, std::set< HepMC::GenVertexPtr > &visited, int level, std::set< HepMC::GenParticlePtr, ParticleIdCompare > *particleSet=nullptr)
std::string m_outputKeyName
bool isToBeDecayed(HepMC::ConstGenParticlePtr p, bool doCrossChecks)
bool m_printHepMCHighLightTopLevelDecays
std::string m_inputKeyName
bool m_allowAllKnownDecays
std::string pdgName(HepMC::ConstGenParticlePtr p, bool statusHighlighting=false, std::set< HepMC::GenParticlePtr, ParticleIdCompare > *particleSet=nullptr)
std::map< int, long > m_noDecayChannels
bool m_prohibitFinalStateDecay
bool m_printHepMCHighlighted
void decayParticle(HepMC::GenEvent *hepMC, HepMC::GenParticlePtr p)
EvtInclusiveAtRndmGen * m_evtAtRndmGen
EvtInclusiveDecay(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< int > m_whiteList
virtual StatusCode initialize() override
GenBase(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
void calculateSeedsMC21(long *seeds, const std::string &algName, uint64_t ev, uint64_t run, uint64_t offset=0)
Set the random seed using a string (e.g.
void setExtendedEventContext(EventContext &ctx, ExtendedEventContext &&ectx)
Move an extended context into a context object.
void line(std::ostream &os, const GenEvent &e)
HepMC::GenVertex * GenVertexPtr
GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), const int i=0)
GenParticlePtr newGenParticlePtr(const HepMC::FourVector &mom=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), int pid=0, int status=0)
void fillBarcodesAttribute(GenEvent *)
GenParticle * GenParticlePtr
const GenParticle * ConstGenParticlePtr
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isDecayed(const T &p)
Identify if the particle decayed.
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.