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"
58 m_nRepeatedDecays(0) {
124 msg(MSG::INFO) <<
"EvtInclusiveDecay initialize" <<
endmsg;
129 msg(MSG::INFO) <<
"EvtInclusiveDecay selection parameters:" <<
endmsg;
136 msg(MSG::INFO) <<
"User selection parameters:" <<
endmsg;
148 msg(MSG::INFO) <<
"* blackList; = ";
150 msg(MSG::INFO) << (*i) <<
" ";
155 msg(MSG::INFO) <<
"* whiteList = ";
157 msg(MSG::INFO) << (*i) <<
" ";
165 EvtExternalGenList genList(
true,
xmlpath(),
"gamma");
166 EvtAbsRadCorr* radCorrEngine = genList.getPhotosModel();
167 std::list<EvtDecayBase*> extraModels = genList.getListOfModels();
178 return StatusCode::SUCCESS;
183 const EventContext& ctx)
192 const EventContext& ctx)
const
195 rngWrapper->
setSeed(
streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
205 ctx.setEventID (EventIDBase (conditionsRun,
206 EventIDBase::UNDEFEVT,
207 EventIDBase::UNDEFNUM,
208 EventIDBase::UNDEFNUM,
220 const EventContext& ctx = Gaudi::Hive::currentContext();
244 HepMC::GenEvent* hepMC = *mcItr;
249 std::set<HepMC::GenVertexPtr> visited;
251 std::set<HepMC::GenParticlePtr> toBeDecayed;
252 for (
auto p: hepMC->particles()) {
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;
269 std::set<int> toBeDecayed;
270 for (HepMC::GenEvent::particle_iterator
itp = hepMC->particles_begin();
itp != hepMC->particles_end(); ++
itp) {
272 if ( (!
p->production_vertex()) ||
273 (
p->production_vertex()->particles_in_size() == 0) ) {
276 return StatusCode::FAILURE;
281 msg(MSG::INFO) <<
"Printing HepMC record at " << hepMC <<
" BEFORE running EvtGen:" <<
endmsg;
290 bool eventPassesCuts(
false);
294 for (
auto p: toBeDecayed) {
296 msg(MSG::ERROR ) <<
"Overlapping decay tree for particle" <<
p <<
endmsg;
297 return StatusCode::FAILURE;
304 auto p = hepMC->barcode_to_particle(*itb);
306 msg(MSG::ERROR ) <<
"Overlapping decay tree encountered for barcode " << *itb <<
endmsg;
307 return StatusCode::FAILURE;
317 eventPassesCuts =
true;
326 hepMC->weight(
"nEvtGenDecayAttempts") = loopCounter;
329 hepMC->weights()[
"nEvtGenDecayAttempts"] = loopCounter;
333 msg(MSG::INFO) <<
"Printing HepMC record at " << hepMC <<
" AFTER running EvtGen:" <<
endmsg;
345 return StatusCode::SUCCESS;
352 ATH_MSG_INFO(
"The following particles were checked and didn't have any decay channels:");
354 std::cout << std::endl;
355 std::cout <<
" Particle code Name from HepPDT # Occurences" << std::endl;
356 std::cout <<
"------------------------------------------------------" << std::endl;
360 std::cout << std::setw(14) <<
id
362 << std::setw(20) <<
count
365 std::cout << std::endl;
370 return StatusCode::SUCCESS;
385 std::set<HepMC::GenVertexPtr>& visited,
386 std::set<HepMC::GenParticlePtr>& toBeDecayed) {
390 std::set<HepMC::GenVertexPtr>& visited,
391 std::set<int>& toBeDecayed) {
394 if (!isToBeRemoved) {
397 toBeDecayed.insert(
p);
401 isToBeRemoved =
true;
411 auto v =
p->end_vertex();
414 if (visited.insert(
v).second) {
416 ATH_MSG_WARNING(
"Found particle to be decayed with vertex with >1 incoming mother particles in decay tree");
419 for (
auto itp:
v->particles_out()) {
426 if (visited.insert(
v).second) {
429 ATH_MSG_WARNING(
"Found particle to be decayed with vertex with >1 incoming mother particles in decay tree");
438 return StatusCode::SUCCESS;
447 auto v =
p->end_vertex();
451 hepMC->remove_vertex(
v);
455 std::set<int> vtxBarCodesToDelete;
456 vtxBarCodesToDelete.insert(
v->barcode());
457 for (HepMC::GenVertex::vertex_iterator itv =
v->vertices_begin(HepMC::descendants);
458 itv !=
v->vertices_end(HepMC::descendants);
460 vtxBarCodesToDelete.insert((*itv)->barcode());
462 auto vdel = hepMC->barcode_to_vertex(*itb);
463 hepMC->remove_vertex(vdel);
468 <<
" decay tree with " << vtxBarCodesToDelete.size() <<
" vertices");
500 int id =
part->pdg_id();
501 EvtId evtId=EvtPDL::evtIdFromStdHep(
id);
502 double en =(
part->momentum()).
e()/1000.;
503 double px=(
part->momentum()).
px()/1000.;
504 double py=(
part->momentum()).
py()/1000.;
505 double pz=(
part->momentum()).
pz()/1000.;
507 EvtParticle* evtPart = EvtParticleFactory::particleFactory(evtId,evtP);
510 if(
m_setVMtransversePol && (
id==113 ||
id== 443 ||
id==100443 ||
id==553 ||
id==100553 ||
id==200553) )evtPart->setVectorSpinDensity();
514 double ct_s =
part->production_vertex()->position().t();
515 double x_s =
part->production_vertex()->position().x();
516 double y_s =
part->production_vertex()->position().y();
517 double z_s =
part->production_vertex()->position().z();
519 EvtVector4R treeStart(ct_s,x_s,y_s,z_s);
522 if(evtPart->getNDaug() !=0)
part->set_status(2);
523 evtPart->deleteTree();
529 EvtParticle* evtPart, EvtVector4R treeStart,
double momentumScaleFactor) {
530 if(evtPart->getNDaug()!=0) {
532 double ct=(evtPart->getDaug(0)->get4Pos()).
get(0)+treeStart.get(0);
533 double x=(evtPart->getDaug(0)->get4Pos()).
get(1)+treeStart.get(1);
534 double y=(evtPart->getDaug(0)->get4Pos()).
get(2)+treeStart.get(2);
535 double z=(evtPart->getDaug(0)->get4Pos()).
get(3)+treeStart.get(3);
539 hepMC->add_vertex(end_vtx);
540 end_vtx->add_particle_in(
part);
543 for(
uint it=0;
it<evtPart->getNDaug();
it++) {
544 double e=(evtPart->getDaug(
it)->getP4Lab()).
get(0) * momentumScaleFactor;
545 double px=(evtPart->getDaug(
it)->getP4Lab()).
get(1) * momentumScaleFactor;
546 double py=(evtPart->getDaug(
it)->getP4Lab()).
get(2) * momentumScaleFactor;
547 double pz=(evtPart->getDaug(
it)->getP4Lab()).
get(3) * momentumScaleFactor;
548 int id=EvtPDL::getStdHep(evtPart->getDaug(
it)->getId());
550 if(evtPart->getDaug(
it)->getNDaug() != 0)
status=2;
552 end_vtx->add_particle_out(daughter);
567 int id =
p->pdg_id();
569 auto v =
p->end_vertex();
570 if (
v) nDaughters =
v->particles_out_size();
573 if (
p->status() == 3)
return false;
579 double m2 =
p->momentum().m2();
586 EvtId evtId = EvtPDL::evtIdFromStdHep(
id);
589 if (evtId.getId()>=0)
591 nModes = EvtDecayTable::getInstance()->getNMode(evtId.getAlias());
594 <<
" (status = " <<
p->status()
595 <<
") -- " << nModes <<
" decay modes found");
613 for (
auto itd:
v->particles_out()) {
614 if (std::abs(itd->pdg_id()) == std::abs(
id))
return false;
617 for (HepMC::GenVertex::particle_iterator itd =
v->particles_begin(
HepMC::children);
620 if (std::abs((*itd)->pdg_id()) == std::abs(
id))
return false;
644 int id = std::abs(pId);
667 std::vector<HepMC::GenParticlePtr> *muons =
new std::vector<HepMC::GenParticlePtr>;
669 for (
const auto&
p: *hepMC) {
670 if( std::abs(
p->pdg_id()) == 13 )
674 for (
auto muItr1 = muons->begin(); muItr1 != muons->end(); ++muItr1) {
675 for (
auto muItr2 = muItr1+1; muItr2 != muons->end(); ++muItr2) {
683 double dimuMass =
invMass((*muItr1),(*muItr2));
696 double p1Px =
p1->momentum().px();
697 double p1Py =
p1->momentum().py();
698 double p1Pz =
p1->momentum().pz();
699 double p1E =
p1->momentum().e();
700 double p2Px =
p2->momentum().px();
701 double p2Py =
p2->momentum().py();
702 double p2Pz =
p2->momentum().pz();
703 double p2E =
p2->momentum().e();
704 double dimuE = p2E + p1E;
705 double dimuPx = p2Px + p1Px;
706 double dimuPy = p2Py + p1Py;
707 double dimuPz = p2Pz + p1Pz;
708 double invMass = std::sqrt(dimuE*dimuE - dimuPx*dimuPx - dimuPy*dimuPy - dimuPz*dimuPz);
720 std::set<HepMC::GenVertexPtr> visited;
721 unsigned int nParticlesFound = 0;
722 unsigned int nTreesFound = 0;
723 for (
auto p: *hepMC) {
724 if ( (!
p->production_vertex()) ||
725 (
p->production_vertex()->particles_in().size() == 0) ) {
727 std::cout <<
"\n Found new partial decay tree:\n" << std::endl;
728 unsigned int nParticlesVisited =
printTree(
p,visited,1,barcodeList);
729 std::cout <<
"\n " << nParticlesVisited <<
" particles in this subtree" << std::endl;
730 nParticlesFound += nParticlesVisited;
733 std::cout <<
"\n Total of " << nParticlesFound <<
" particles found in "
734 << nTreesFound <<
" decay subtrees in HepMC event record\n" << std::endl;
738 std::set<HepMC::GenVertexPtr> visited;
739 unsigned int nParticlesFound = 0;
740 unsigned int nTreesFound = 0;
741 for (HepMC::GenEvent::particle_iterator
itp = hepMC->particles_begin();
itp != hepMC->particles_end(); ++
itp) {
743 if ( (!
p->production_vertex()) ||
744 (
p->production_vertex()->particles_in_size() == 0) ) {
746 std::cout <<
"\n Found new partial decay tree:\n" << std::endl;
747 unsigned int nParticlesVisited =
printTree(
p,visited,1,barcodeList);
748 std::cout <<
"\n " << nParticlesVisited <<
" particles in this subtree" << std::endl;
749 nParticlesFound += nParticlesVisited;
752 std::cout <<
"\n Total of " << nParticlesFound <<
" particles found in "
753 << nTreesFound <<
" decay subtrees in HepMC event record\n" << std::endl;
759 std::set<HepMC::GenVertexPtr>& visited,
int level, std::set<HepMC::GenParticlePtr>* barcodeList) {
760 unsigned int nParticlesVisited = 1;
761 for (
int i=0;
i<
level;
i++) std::cout <<
" ";
763 auto v =
p->end_vertex();
765 if (
v->particles_in().size() > 1)
766 std::cout <<
" [interaction: " <<
v->particles_in().size() <<
" particles, vertex " <<
v <<
"] --> ";
768 std::cout <<
" --> ";
769 if (visited.insert(
v).second) {
770 for (
auto itp:
v->particles_out()) {
773 std::cout << std::endl;
774 for (
auto itp:
v->particles_out()) {
775 if (
itp->end_vertex())
781 std::cout <<
"see above" << std::endl;
783 std::cout <<
" no decay vertex\n" << std::endl;
784 return nParticlesVisited;
788 std::set<HepMC::GenVertexPtr>& visited,
int level, std::set<int>* barcodeList) {
789 unsigned int nParticlesVisited = 1;
790 for (
int i=0;
i<
level;
i++) std::cout <<
" ";
792 auto v =
p->end_vertex();
794 if (
v->particles_in_size() > 1)
795 std::cout <<
" [interaction: " <<
v->particles_in_size() <<
" particles, vertex " <<
v <<
"] --> ";
797 std::cout <<
" --> ";
798 if (visited.insert(
v).second) {
804 std::cout << std::endl;
808 if ((*itp)->end_vertex())
814 std:: cout <<
"see above" << std::endl;
816 std::cout <<
" no decay vertex\n" << std::endl;
817 return nParticlesVisited;
823 std::ostringstream buf;
825 if (barcodeList)
for (
const auto& pinl: *barcodeList)
if (pinl&&
p)
if (pinl.get()==
p.get()) inlist=
true;
826 if (statusHighlighting) {
827 if ( ((barcodeList!=0) && (inlist)) ||
839 if (statusHighlighting) {
846 std::ostringstream buf;
847 if (statusHighlighting) {
848 if ( ((barcodeList!=0) && (barcodeList->find(
HepMC::barcode(
p)) != barcodeList->end())) ||
860 if (statusHighlighting) {
877 return CLHEP::RandFlat::shoot(
m_engine);