21 #include "EvtGenBase/EvtAbsRadCorr.hh"
22 #include "EvtGenBase/EvtDecayBase.hh"
23 #include "EvtGen_i/EvtGenExternal/EvtExternalGenList.hh"
25 #include "EvtGenBase/EvtVector4R.hh"
26 #include "EvtGenBase/EvtParticle.hh"
27 #include "EvtGenBase/EvtParticleFactory.hh"
28 #include "EvtGen/EvtGen.hh"
29 #include "EvtGenBase/EvtRandomEngine.hh"
30 #include "EvtGenBase/EvtDecayTable.hh"
40 #include "GaudiKernel/MsgStream.h"
41 #include "GaudiKernel/ISvcLocator.h"
42 #include "GaudiKernel/DataSvc.h"
43 #include "GaudiKernel/IPartPropSvc.h"
47 #include "HepPID/ParticleName.hh"
50 #include "CLHEP/Random/RandFlat.h"
51 #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();
181 return StatusCode::SUCCESS;
186 const EventContext& ctx)
195 const EventContext& ctx)
const
198 rngWrapper->
setSeed(
streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
208 ctx.setEventID (EventIDBase (conditionsRun,
209 EventIDBase::UNDEFEVT,
210 EventIDBase::UNDEFNUM,
211 EventIDBase::UNDEFNUM,
223 const EventContext& ctx = Gaudi::Hive::currentContext();
247 HepMC::GenEvent* hepMC = *mcItr;
252 std::set<HepMC::GenVertexPtr> visited;
254 std::set<HepMC::GenParticlePtr> toBeDecayed;
255 for (
auto p: hepMC->particles()) {
256 if ( (!
p->production_vertex()) ||
257 (
p->production_vertex()->particles_in().size() == 0) ) {
260 return StatusCode::FAILURE;
265 msg(MSG::INFO) <<
"Printing HepMC record at " << hepMC <<
" BEFORE running EvtGen:" <<
endmsg;
272 std::set<int> toBeDecayed;
273 for (HepMC::GenEvent::particle_iterator
itp = hepMC->particles_begin();
itp != hepMC->particles_end(); ++
itp) {
275 if ( (!
p->production_vertex()) ||
276 (
p->production_vertex()->particles_in_size() == 0) ) {
279 return StatusCode::FAILURE;
284 msg(MSG::INFO) <<
"Printing HepMC record at " << hepMC <<
" BEFORE running EvtGen:" <<
endmsg;
293 bool eventPassesCuts(
false);
297 for (
auto p: toBeDecayed) {
299 msg(MSG::ERROR ) <<
"Overlapping decay tree for particle" <<
p <<
endmsg;
300 return StatusCode::FAILURE;
307 auto p = hepMC->barcode_to_particle(*itb);
309 msg(MSG::ERROR ) <<
"Overlapping decay tree encountered for barcode " << *itb <<
endmsg;
310 return StatusCode::FAILURE;
320 eventPassesCuts =
true;
329 hepMC->weight(
"nEvtGenDecayAttempts") = loopCounter;
332 hepMC->weights()[
"nEvtGenDecayAttempts"] = loopCounter;
336 msg(MSG::INFO) <<
"Printing HepMC record at " << hepMC <<
" AFTER running EvtGen:" <<
endmsg;
348 return StatusCode::SUCCESS;
355 ATH_MSG_INFO(
"The following particles were checked and didn't have any decay channels:");
357 std::cout << std::endl;
358 std::cout <<
" Particle code Name from HepPDT # Occurences" << std::endl;
359 std::cout <<
"------------------------------------------------------" << std::endl;
363 std::cout << std::setw(14) <<
id
365 << std::setw(20) <<
count
368 std::cout << std::endl;
373 return StatusCode::SUCCESS;
388 std::set<HepMC::GenVertexPtr>& visited,
389 std::set<HepMC::GenParticlePtr>& toBeDecayed) {
393 std::set<HepMC::GenVertexPtr>& visited,
394 std::set<int>& toBeDecayed) {
397 if (!isToBeRemoved) {
400 toBeDecayed.insert(
p);
404 isToBeRemoved =
true;
414 auto v =
p->end_vertex();
417 if (visited.insert(
v).second) {
419 ATH_MSG_WARNING(
"Found particle to be decayed with vertex with >1 incoming mother particles in decay tree");
422 for (
auto itp:
v->particles_out()) {
429 if (visited.insert(
v).second) {
432 ATH_MSG_WARNING(
"Found particle to be decayed with vertex with >1 incoming mother particles in decay tree");
441 return StatusCode::SUCCESS;
450 auto v =
p->end_vertex();
454 hepMC->remove_vertex(
v);
458 std::set<int> vtxBarCodesToDelete;
459 vtxBarCodesToDelete.insert(
v->barcode());
460 for (HepMC::GenVertex::vertex_iterator itv =
v->vertices_begin(HepMC::descendants);
461 itv !=
v->vertices_end(HepMC::descendants);
463 vtxBarCodesToDelete.insert((*itv)->barcode());
465 auto vdel = hepMC->barcode_to_vertex(*itb);
466 hepMC->remove_vertex(vdel);
471 <<
" decay tree with " << vtxBarCodesToDelete.size() <<
" vertices");
503 int id =
part->pdg_id();
504 EvtId evtId=EvtPDL::evtIdFromStdHep(
id);
505 double en =(
part->momentum()).
e()/1000.;
506 double px=(
part->momentum()).
px()/1000.;
507 double py=(
part->momentum()).
py()/1000.;
508 double pz=(
part->momentum()).
pz()/1000.;
510 EvtParticle* evtPart = EvtParticleFactory::particleFactory(evtId,evtP);
513 if(
m_setVMtransversePol && (
id==113 ||
id== 443 ||
id==100443 ||
id==553 ||
id==100553 ||
id==200553) )evtPart->setVectorSpinDensity();
517 double ct_s =
part->production_vertex()->position().t();
518 double x_s =
part->production_vertex()->position().x();
519 double y_s =
part->production_vertex()->position().y();
520 double z_s =
part->production_vertex()->position().z();
522 EvtVector4R treeStart(ct_s,x_s,y_s,z_s);
525 if(evtPart->getNDaug() !=0)
part->set_status(2);
526 evtPart->deleteTree();
532 EvtParticle* evtPart, EvtVector4R treeStart,
double momentumScaleFactor) {
533 if(evtPart->getNDaug()!=0) {
535 double ct=(evtPart->getDaug(0)->get4Pos()).
get(0)+treeStart.get(0);
536 double x=(evtPart->getDaug(0)->get4Pos()).
get(1)+treeStart.get(1);
537 double y=(evtPart->getDaug(0)->get4Pos()).
get(2)+treeStart.get(2);
538 double z=(evtPart->getDaug(0)->get4Pos()).
get(3)+treeStart.get(3);
542 hepMC->add_vertex(end_vtx);
543 end_vtx->add_particle_in(
part);
546 for(
uint it=0;
it<evtPart->getNDaug();
it++) {
547 double e=(evtPart->getDaug(
it)->getP4Lab()).
get(0) * momentumScaleFactor;
548 double px=(evtPart->getDaug(
it)->getP4Lab()).
get(1) * momentumScaleFactor;
549 double py=(evtPart->getDaug(
it)->getP4Lab()).
get(2) * momentumScaleFactor;
550 double pz=(evtPart->getDaug(
it)->getP4Lab()).
get(3) * momentumScaleFactor;
551 int id=EvtPDL::getStdHep(evtPart->getDaug(
it)->getId());
553 if(evtPart->getDaug(
it)->getNDaug() != 0)
status=2;
555 end_vtx->add_particle_out(daughter);
570 int id =
p->pdg_id();
572 auto v =
p->end_vertex();
573 if (
v) nDaughters =
v->particles_out_size();
576 if (
p->status() == 3)
return false;
582 double m2 =
p->momentum().m2();
589 EvtId evtId = EvtPDL::evtIdFromStdHep(
id);
592 if (evtId.getId()>=0)
594 nModes = EvtDecayTable::getInstance()->getNMode(evtId.getAlias());
597 <<
" (status = " <<
p->status()
598 <<
") -- " << nModes <<
" decay modes found");
616 for (
auto itd:
v->particles_out()) {
617 if (std::abs(itd->pdg_id()) == std::abs(
id))
return false;
620 for (HepMC::GenVertex::particle_iterator itd =
v->particles_begin(
HepMC::children);
623 if (std::abs((*itd)->pdg_id()) == std::abs(
id))
return false;
647 int id = std::abs(pId);
670 std::vector<HepMC::GenParticlePtr> *muons =
new std::vector<HepMC::GenParticlePtr>;
672 for (
const auto&
p: *hepMC) {
673 if( std::abs(
p->pdg_id()) == 13 )
677 for (
auto muItr1 = muons->begin(); muItr1 != muons->end(); ++muItr1) {
678 for (
auto muItr2 = muItr1+1; muItr2 != muons->end(); ++muItr2) {
686 double dimuMass =
invMass((*muItr1),(*muItr2));
699 double p1Px =
p1->momentum().px();
700 double p1Py =
p1->momentum().py();
701 double p1Pz =
p1->momentum().pz();
702 double p1E =
p1->momentum().e();
703 double p2Px =
p2->momentum().px();
704 double p2Py =
p2->momentum().py();
705 double p2Pz =
p2->momentum().pz();
706 double p2E =
p2->momentum().e();
707 double dimuE = p2E + p1E;
708 double dimuPx = p2Px + p1Px;
709 double dimuPy = p2Py + p1Py;
710 double dimuPz = p2Pz + p1Pz;
711 double invMass = std::sqrt(dimuE*dimuE - dimuPx*dimuPx - dimuPy*dimuPy - dimuPz*dimuPz);
723 std::set<HepMC::GenVertexPtr> visited;
724 unsigned int nParticlesFound = 0;
725 unsigned int nTreesFound = 0;
726 for (
auto p: *hepMC) {
727 if ( (!
p->production_vertex()) ||
728 (
p->production_vertex()->particles_in().size() == 0) ) {
730 std::cout <<
"\n Found new partial decay tree:\n" << std::endl;
731 unsigned int nParticlesVisited =
printTree(
p,visited,1,barcodeList);
732 std::cout <<
"\n " << nParticlesVisited <<
" particles in this subtree" << std::endl;
733 nParticlesFound += nParticlesVisited;
736 std::cout <<
"\n Total of " << nParticlesFound <<
" particles found in "
737 << nTreesFound <<
" decay subtrees in HepMC event record\n" << std::endl;
741 std::set<HepMC::GenVertexPtr> visited;
742 unsigned int nParticlesFound = 0;
743 unsigned int nTreesFound = 0;
744 for (HepMC::GenEvent::particle_iterator
itp = hepMC->particles_begin();
itp != hepMC->particles_end(); ++
itp) {
746 if ( (!
p->production_vertex()) ||
747 (
p->production_vertex()->particles_in_size() == 0) ) {
749 std::cout <<
"\n Found new partial decay tree:\n" << std::endl;
750 unsigned int nParticlesVisited =
printTree(
p,visited,1,barcodeList);
751 std::cout <<
"\n " << nParticlesVisited <<
" particles in this subtree" << std::endl;
752 nParticlesFound += nParticlesVisited;
755 std::cout <<
"\n Total of " << nParticlesFound <<
" particles found in "
756 << nTreesFound <<
" decay subtrees in HepMC event record\n" << std::endl;
762 std::set<HepMC::GenVertexPtr>& visited,
int level, std::set<HepMC::GenParticlePtr>* barcodeList) {
763 unsigned int nParticlesVisited = 1;
764 for (
int i=0;
i<
level;
i++) std::cout <<
" ";
766 auto v =
p->end_vertex();
768 if (
v->particles_in().size() > 1)
769 std::cout <<
" [interaction: " <<
v->particles_in().size() <<
" particles, vertex " <<
v <<
"] --> ";
771 std::cout <<
" --> ";
772 if (visited.insert(
v).second) {
773 for (
auto itp:
v->particles_out()) {
776 std::cout << std::endl;
777 for (
auto itp:
v->particles_out()) {
778 if (
itp->end_vertex())
784 std::cout <<
"see above" << std::endl;
786 std::cout <<
" no decay vertex\n" << std::endl;
787 return nParticlesVisited;
791 std::set<HepMC::GenVertexPtr>& visited,
int level, std::set<int>* barcodeList) {
792 unsigned int nParticlesVisited = 1;
793 for (
int i=0;
i<
level;
i++) std::cout <<
" ";
795 auto v =
p->end_vertex();
797 if (
v->particles_in_size() > 1)
798 std::cout <<
" [interaction: " <<
v->particles_in_size() <<
" particles, vertex " <<
v <<
"] --> ";
800 std::cout <<
" --> ";
801 if (visited.insert(
v).second) {
807 std::cout << std::endl;
811 if ((*itp)->end_vertex())
817 std:: cout <<
"see above" << std::endl;
819 std::cout <<
" no decay vertex\n" << std::endl;
820 return nParticlesVisited;
826 std::ostringstream buf;
828 if (barcodeList)
for (
const auto& pinl: *barcodeList)
if (pinl&&
p)
if (pinl.get()==
p.get()) inlist=
true;
829 if (statusHighlighting) {
830 if ( ((barcodeList!=0) && (inlist)) ||
842 if (statusHighlighting) {
849 std::ostringstream buf;
850 if (statusHighlighting) {
851 if ( ((barcodeList!=0) && (barcodeList->find(
HepMC::barcode(
p)) != barcodeList->end())) ||
863 if (statusHighlighting) {
880 return CLHEP::RandFlat::shoot(
m_engine);
885 static void local_split( std::vector <std::string>&
tokens,
const std::string&
input,
const char sep) {
887 for (
size_t i = 0;
i <=
input.size();
i++) {
898 char *cmtpath =
getenv(
"CMTPATH");
899 char *cmtconfig =
getenv(
"CMTCONFIG");
901 std::string foundpath =
"";
903 if(cmtpath != 0 && cmtconfig != 0){
905 std::vector<std::string> cmtpaths;
906 local_split(cmtpaths, cmtpath,
':');
908 std::string
installPath =
"/InstallArea/" + std::string(cmtconfig) +
"/share/Pythia8/xmldoc";
910 for(std::vector<std::string>::const_iterator
path = cmtpaths.begin();
911 path != cmtpaths.end() && foundpath ==
""; ++
path){
913 std::ifstream
testFile(testPath.c_str());
914 if(
testFile.good()) foundpath = testPath;