#include "SHERPA/SoftPhysics/Resonance_Finder.H" #include "ATOOLS/Org/Scoped_Settings.H" #include "ATOOLS/Org/Message.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Phys/Blob.H" #include "ATOOLS/Phys/Blob_List.H" #include "ATOOLS/Phys/KF_Table.H" #include "ATOOLS/Phys/Particle.H" #include "MODEL/Main/Model_Base.H" #include "MODEL/Main/Single_Vertex.H" #include "PHASIC++/Process/Process_Base.H" #include "PHASIC++/Process/Process_Info.H" #include "PHASIC++/Process/Subprocess_Info.H" #include "SHERPA/PerturbativePhysics/Matrix_Element_Handler.H" using namespace SHERPA; using namespace ATOOLS; using namespace PHASIC; using namespace MODEL; using namespace std; Resonance_Finder::Resonance_Finder(Matrix_Element_Handler* meh) : p_mehandler(meh), m_on(false) { if (meh) { Scoped_Settings meqedsettings{Settings::GetMainSettings()["ME_QED"] }; m_on = meqedsettings["CLUSTERING_ENABLED"].SetDefault(true).Get(); m_resdist = meqedsettings["CLUSTERING_THRESHOLD"].SetDefault(10.0).Get(); m_inclres = meqedsettings["INCLUDE_RESONANCES"].SetDefault(false).Get(); InitialiseHelperParticles(); } if (m_on) { ScanModelForEWResonances(); IdentifyEWSubprocesses(); } } Resonance_Finder::~Resonance_Finder() {} void Resonance_Finder::ScanModelForEWResonances() { Process_Vector pvec(p_mehandler->AllProcesses()); for (size_t i=0;iSize();++j) { Vertex_List vlist; FindProcessPossibleResonances((*pvec[i])[j]->Flavours(),vlist); msg_Debugging()<<"Process: "<<(*pvec[i])[j]->Name()<<" -> " <Name()]=vlist; } } } void Resonance_Finder::FindProcessPossibleResonances (const Flavour_Vector& fv, MODEL::Vertex_List& vlist) { const Vertex_Table *vtab(s_model->VertexTable()); Flavour_Vector fslep; for (size_t i(2);ibegin());it!=vtab->end();++it) { if (it->first.IsOn() && !it->first.Strong() && it->first.IsMassive() && !it->first.IsDummy()) { for (size_t i(0);isecond.size();++i) { bool on(true); double m(it->first.Mass()); Single_Vertex * v(it->second[i]); for (size_t j(1);jin.size();++j) { if (v->dec) { on=false; break; } if (v->in[j]==v->in[0].Bar()){ on=false; break; } if (v->in[j].IsDummy()) { on=false; break; } if ((m-=v->in[j].Mass())<0.) { on=false; break; } bool flavfound(false); for (size_t k(0);kin[j]==fslep[k]) { flavfound=true; break; } if (!flavfound) { on=false; break; } } if (on) vlist.push_back(v); } } } } void Resonance_Finder::InitialiseHelperParticles() { // Need to use full Particle_Info constructor here. Arguments are: /* const kf_code &kfc, const double &mass, const double &width, const int icharge, const int strong, const int spin, const int majorana, const bool on, const int stable, bool massive, const std::string &idname, const std::string &antiname, const std::string& texname, const std::string &antitexname, const bool dummy, const bool isgroup */ if(s_kftable.find(kf_PhotonsHelperNeutral)==s_kftable.end()) s_kftable[kf_PhotonsHelperNeutral] =new Particle_Info(kf_PhotonsHelperNeutral,0.0,0.0,0.0,0,0,0,0,1,1,0, "PH0","PH0b","H_P^{0}","\\overline{H_P^{0}}",0,0); if(s_kftable.find(kf_PhotonsHelperPlus)==s_kftable.end()) s_kftable[kf_PhotonsHelperPlus] =new Particle_Info(kf_PhotonsHelperPlus,0.0,0.0,0.0,3,0,0,0,1,1,0, "PH+","PH-","H_P^{+}","H_P^{-}",0,0); if(s_kftable.find(kf_PhotonsHelperPlusPlus)==s_kftable.end()) s_kftable[kf_PhotonsHelperPlusPlus] =new Particle_Info(kf_PhotonsHelperPlusPlus,0.0,0.0,0.0,6,0,0,0,1,1,0, "PH++","PH--","H_P^{++}","H_P^{--}",0,0); if(s_kftable.find(kf_PhotonsHelperPlusPlusPlus)==s_kftable.end()) s_kftable[kf_PhotonsHelperPlusPlusPlus] =new Particle_Info(kf_PhotonsHelperPlusPlusPlus,0.0,0.0,0.0,9,0,0,0,1,1,0, "PH+++","PH---","H_P^{+++}","H_P^{---}",0,0); } void Resonance_Finder::IdentifyEWSubprocesses() { Process_Vector pvec(p_mehandler->AllProcesses()); for (size_t i=0;iSize();++j) { SubInfoVector siv; FindSubProcessInfosContainingLeptons((*pvec[i])[j]->Info(),siv); msg_Debugging()<<"Process: "<<(*pvec[i])[j]->Name()<<" -> " <Name(),siv)); } } } void Resonance_Finder::FindSubProcessInfosContainingLeptons (const Process_Info& pi, SubInfoVector& siv) { // loop over FS of process -> find subprocs, that are subsequent decays for (size_t i=0;i1) FindSubProcessInfosContainingLeptons(pi.m_fi.m_ps[i],siv); } } void Resonance_Finder::FindSubProcessInfosContainingLeptons (const Subprocess_Info& spi, SubInfoVector& siv) { // assume connected leptons are produced in same subprocess info size_t count(0), leps(0); for (size_t i=0;i final subprocess info // if contains leptons, add to siv siv.push_back(&spi); } } void Resonance_Finder::BuildResonantBlobs (Particle_Vector& pv, Blob_Vector& blobs) { BuildResonantBlobs(pv, blobs, p_mehandler->Process()); } void Resonance_Finder::BuildResonantBlobs (Particle_Vector& pv, Blob_Vector& blobs, Process_Base* proc) { DEBUG_FUNC(pv.size()<<" particles to treat, clustering = "<Name()); SubInfoVector siv(m_proc_lep_map[name]); // create blobs accordingly (only if lepton list is unambiguous) msg_Debugging()<InParticle(0)); } } // find/reconstruct possible resonances in the final state std::vector rpvs; std::vector rfl; const Vertex_List& vlist(m_proc_restab_map[name]); if (m_on && pv.size()>1 && FindResonances(pv,rpvs,rfl,vlist)) { for (size_t i=0;iInParticle(0)); } } // otherwise create global resonant blob // if there are leptons not contained in defined resonant blobs if (pv.size()) { blobs.insert(blobs.begin(),new Blob(Vec4D(0.,0.,0.,0.))); FillBlob(*blobs.begin(),DetermineGenericResonance(pv),pv); msg_Debugging()<<"built generic blob:"< checklist; for (size_t i=0;iFlav().IDName()) == checklist.end()) checklist.insert(pv[i]->Flav().IDName()); else return false; } return true; } void Resonance_Finder::FillBlob (Blob * blob, const Subprocess_Info& spi, Particle_Vector& pv) { DEBUG_FUNC(pv.size()); // find the leptons owned by this subprocess Particle_Vector localpv; bool onlyleptons(true); for (size_t i=0;iFlav()==spi.m_ps[i].m_fl) { localpv.push_back(*it); pv.erase(it); } else ++it; } } if (onlyleptons) FillBlob(blob,spi.m_fl,localpv); else FillBlob(blob,DetermineGenericResonance(localpv),localpv); } void Resonance_Finder::FillBlob (Blob * blob, const Flavour& resflav, Particle_Vector& pv) { DEBUG_FUNC(resflav); Vec4D sum(MomentumSum(pv)); for (Particle_Vector::iterator it=pv.begin();it!=pv.end();) { blob->AddToOutParticles(*it); pv.erase(it); } blob->AddToInParticles(new Particle(-1,resflav,sum,'R')); blob->InParticle(0)->SetFinalMass(blob->InParticle(0)->Momentum().Mass()); blob->AddData("p_original", new Blob_Data(blob->InParticle(0)->Momentum())); } bool Resonance_Finder::FindResonances (Particle_Vector& pv,std::vector& rpvs,Flavour_Vector& rfl, const Vertex_List& vlist) { if (vlist.empty()) return false; DEBUG_FUNC("find resonances in "< > restab; for (size_t i(0);iMomentum()+pv[j]->Momentum()).Mass() -vlist[k]->in[0].Mass())/vlist[k]->in[0].Width()); if (vlist[k]->in.size()==3 && ((pv[i]->Flav()==vlist[k]->in[1] && pv[j]->Flav()==vlist[k]->in[2]) || (pv[i]->Flav()==vlist[k]->in[2] && pv[j]->Flav()==vlist[k]->in[1])) && mdist(ida,ida+3); } } } } if (restab.empty()) { msg_Debugging()<<"no resonances found"< >::const_iterator it=restab.begin();it!=restab.end();++it) msg_Debugging()<second[0]<second[1]<second[2]<<": " <second[2]]->in[0].Bar()<<" -> " <second[2]]->in[1]<<" " <second[2]]->in[2] <<", |m-M|/W="<first <<" (max: "< >::const_iterator it=restab.begin(); it!=restab.end();++it) { bool valid(true); for (size_t i(0);isecond[0]]==usedparts[i] || pv[it->second[1]]==usedparts[i]) { valid=false; break; } if (!valid) continue; usedparts.push_back(pv[it->second[0]]); usedparts.push_back(pv[it->second[1]]); msg_Debugging()<<"constructing decay: "<second[2]]->in[0].Bar()<<" -> " <second[2]]->in[1]<<" " <second[2]]->in[2]<<"\n"; rfl.push_back(vlist[it->second[2]]->in[0].Bar()); Particle_Vector parts; parts.push_back(pv[it->second[0]]); parts.push_back(pv[it->second[1]]); rpvs.push_back(parts); } for (Particle_Vector::iterator it=usedparts.begin();it!=usedparts.end();++it) for (Particle_Vector::iterator pit=pv.begin();pit!=pv.end();++pit) if (*it==*pit) { pv.erase(pit); break; } return true; } Flavour Resonance_Finder::DetermineGenericResonance (const Particle_Vector& partvec) { int chargesum(0); for (size_t i=0;iFlav().IntCharge(); if (chargesum==0) return Flavour(kf_PhotonsHelperNeutral); else if (chargesum==3) return Flavour(kf_PhotonsHelperPlus); else if (chargesum==-3) return Flavour(kf_PhotonsHelperPlus).Bar(); else if (chargesum==6) return Flavour(kf_PhotonsHelperPlusPlus); else if (chargesum==-6) return Flavour(kf_PhotonsHelperPlusPlus).Bar(); else if (chargesum==9) return Flavour(kf_PhotonsHelperPlusPlusPlus); else if (chargesum==-9) return Flavour(kf_PhotonsHelperPlusPlusPlus).Bar(); // i got no clue what this might be return Flavour(kf_none); } Vec4D Resonance_Finder::MomentumSum (const Particle_Vector& partvec) { Vec4D sum(0.,0.,0.,0.); for (size_t i=0;iMomentum(); } return sum; }