#include "PHASIC++/Process/Process_Base.H" #include "PHASIC++/Main/Process_Integrator.H" #include "PHASIC++/Scales/Scale_Setter_Base.H" #include "PHASIC++/Scales/KFactor_Setter_Base.H" #include "PHASIC++/Main/Phase_Space_Handler.H" #include "PHASIC++/Main/Phase_Space_Integrator.H" #include "PHASIC++/Selectors/Combined_Selector.H" #include "PHASIC++/Process/Single_Process.H" #include "PHASIC++/Channels/BBar_Multi_Channel.H" #include "MODEL/Main/Single_Vertex.H" #include "MODEL/Main/Model_Base.H" #include "ATOOLS/Phys/Cluster_Amplitude.H" #include "ATOOLS/Phys/Decay_Info.H" #include "ATOOLS/Org/STL_Tools.H" #include "ATOOLS/Org/MyStrStream.H" #include "ATOOLS/Org/Shell_Tools.H" #include "ATOOLS/Org/My_MPI.H" #include "PDF/Main/Shower_Base.H" #include "PDF/Main/ISR_Handler.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Org/Scoped_Settings.H" #include using namespace PHASIC; using namespace MODEL; using namespace ATOOLS; int Process_Base::s_usefmm(-1); Process_Base::Process_Base(): p_parent(NULL), p_selected(this), p_mapproc(NULL), p_sproc(NULL), p_caller(this), p_int(new Process_Integrator(this)), p_selector(NULL), p_cuts(NULL), p_gen(NULL), p_shower(NULL), p_nlomc(NULL), p_mc(NULL), p_scale(NULL), p_kfactor(NULL), m_nin(0), m_nout(0), m_maxcpl(2,99), m_mincpl(2,0), m_mcmode(0), m_cmode(0), m_lookup(false), m_use_biweight(true), m_hasinternalscale(false), m_internalscale(sqr(rpa->gen.Ecms())), p_apmap(NULL), m_last {0, 0.0}, m_lastb {0, 0.0} { if (s_usefmm<0) s_usefmm = Settings::GetMainSettings()["PB_USE_FMM"].SetDefault(0).Get(); } Process_Base::~Process_Base() { if (p_kfactor) delete p_kfactor; if (p_scale) delete p_scale; delete p_selector; delete p_int; } Process_Base *Process_Base::Selected() { if (!p_selected) return NULL; if (p_selected!=this) return p_selected->Selected(); return this; } bool Process_Base::SetSelected(Process_Base *const proc) { if (proc==this) { p_selected=this; return true; } if (IsGroup()) for (size_t i(0);iSetSelected(proc)) { p_selected=(*this)[i]; return true; } return false; } size_t Process_Base::SynchronizeSelectedIndex(Process_Base & proc) { size_t otherindex(proc.SelectedIndex()); if (otherindex < Size()) { SetSelected((*this)[otherindex]); return otherindex; } return std::numeric_limits::max(); } size_t Process_Base::SelectedIndex() { for (size_t i(0); i < Size(); ++i) { if ((*this)[i] == Selected()) { return i; } } return std::numeric_limits::max(); } Process_Base *Process_Base::Parent() { if (p_parent && p_parent!=this) return p_parent->Parent(); return this; } bool Process_Base::GeneratePoint() { return true; } void Process_Base::AddPoint(const double &value) { } bool Process_Base::ReadIn(const std::string &pid) { return true; } void Process_Base::WriteOut(const std::string &pid) { } void Process_Base::EndOptimize() { } void Process_Base::MPICollect(std::vector &sv,size_t &i) { if (IsGroup()) for (size_t j(0);jMPICollect(sv,i); } void Process_Base::MPIReturn(std::vector &sv,size_t &i) { if (IsGroup()) for (size_t j(0);jMPIReturn(sv,i); } void Process_Base::MPISync(const int mode) { if (mode) return; #ifdef USING__MPI size_t i(0), j(0); std::vector sv; MPICollect(sv,i); if (mpi->Size()>1) mpi->Allreduce(&sv[0],sv.size(),MPI_DOUBLE,MPI_SUM); MPIReturn(sv,j); #endif } void Process_Base::SetFixedScale(const std::vector &s) { if (IsMapped()) p_mapproc->SetFixedScale(s); if (p_scale!=NULL) p_scale->SetFixedScale(s); } void Process_Base::SetSelectorOn(const bool on) { Selector()->SetOn(on); } void Process_Base::SetUseBIWeight(bool on) { m_use_biweight=on; } Event_Weights Process_Base::Differential(const Cluster_Amplitude &l, Weight_Type type, int mode) { DEBUG_FUNC(this<<" -> "<Mom(); if (mode&16) THROW(not_implemented,"Invalid mode"); for (size_t i(ampl.NIn());iMom(); if (mode&64) { if (mode&1) return Event_Weights {1, 1.0}; return Event_Weights {1, static_cast(Trigger(p))}; } bool selon(Selector()->On()); if (mode&1) SetSelectorOn(false); if (!Trigger(p)) { if (Selector()->On()!=selon) SetSelectorOn(selon); return 0.0; } if (mode&2) { std::vector s(ScaleSetter(1)->Scales().size(),0.0); s[stp::fac1]=ampl.MuF2(0); s[stp::fac2]=ampl.MuF2(1); s[stp::ren]=ampl.MuR2(); s[stp::res]=ampl.MuQ2(); if (s.size()>stp::size+stp::res) s[stp::size+stp::res]=ampl.KT2(); SetFixedScale(s); } if (mode&4) SetUseBIWeight(false); if (mode&128) { while (!this->GeneratePoint()); } else { std::shared_ptr ci= Integrator()->ColorIntegrator(); if (ci!=nullptr) ci->SetPoint(&l); } Event_Weights wgts {this->Differential(p, type)}; wgts /= m_issymfac; NLO_subevtlist *subs(this->GetSubevtList()); if (subs) { (*subs)*=1.0/m_issymfac; (*subs).MultMEwgt(1.0/m_issymfac); } if (mode&32) { auto psh = Parent()->Integrator()->PSHandler(); wgts*=psh->Weight(p); } if (mode&4) SetUseBIWeight(true); if (mode&2) SetFixedScale(std::vector()); if (Selector()->On()!=selon) SetSelectorOn(selon); return wgts; } bool Process_Base::IsGroup() const { return false; } int Process_Base::PerformTests() { return 1; } bool Process_Base::FillIntegrator (Phase_Space_Handler *const psh) { return false; } bool Process_Base::InitIntegrator (Phase_Space_Handler *const psh) { if (!p_sproc) return true; DEBUG_FUNC(m_name); SetBBarMC(new BBar_Multi_Channel(this,p_sproc,psh)); psh->SetFSRIntegrator(p_mc); return true; } void Process_Base::UpdateIntegrator (Phase_Space_Handler *const psh) { } class Order_NDecay { public: int operator()(const Decay_Info *a,const Decay_Info *b) { return IdCount(a->m_id)>IdCount(b->m_id); } };// end of class Order_NDecay void Process_Base::SortFlavours(Subprocess_Info &info,FMMap *const fmm) { if (info.m_ps.empty()) return; ATOOLS::Flavour heaviest(kf_photon); for (size_t i(0);iheaviest.Mass()) heaviest=info.m_ps[i].m_fl; else if (info.m_ps[i].m_fl.Mass()==heaviest.Mass() && !info.m_ps[i].m_fl.IsAnti()) heaviest=info.m_ps[i].m_fl; } std::sort(info.m_ps.begin(),info.m_ps.end(),Order_Flavour(fmm)); for (size_t i(0);iKfcode()))==fmm.end()) fmm[int(hfl->Kfcode())]=0; if (hfl->IsFermion()) { fmm[int(hfl->Kfcode())]+=10; if (!hfl->IsAnti()) fmm[int(hfl->Kfcode())]+=10; } } for (size_t i(0);iKfcode()))==fmm.end()) fmm[int(hfl->Kfcode())]=0; if (hfl->IsFermion()) fmm[int(hfl->Kfcode())]++; } if (mode&1) SortFlavours(pi.m_ii,s_usefmm?&fmm:NULL); SortFlavours(pi.m_fi,s_usefmm?&fmm:NULL); } bool Process_Base::InitScale() { if (p_scale==NULL) return true; return p_scale->Initialize(); } void Process_Base::Init(const Process_Info &pi, BEAM::Beam_Spectra_Handler *const beamhandler, PDF::ISR_Handler *const isrhandler,const int mode) { m_pinfo=pi; m_nin=m_pinfo.m_ii.NExternal(); m_nout=m_pinfo.m_fi.NExternal(); m_flavs.resize(m_nin+m_nout); if (m_pinfo.m_ii.m_ps.size()>0 && m_pinfo.m_fi.m_ps.size()>0) { if (!(mode&1)) SortFlavours(m_pinfo); std::vector fl; m_pinfo.m_ii.GetExternal(fl); m_pinfo.m_fi.GetExternal(fl); if (fl.size()!=m_nin+m_nout) THROW(fatal_error,"Internal error"); for (size_t i(0);i0 || m_pinfo.m_nmaxqSetISRThreshold(Max(massin,massout)); p_int->Initialize(beamhandler,isrhandler); m_issymfac=1.0; m_symfac=m_pinfo.m_fi.FSSymmetryFactor(); if (m_nin==2 && m_flavs[0]==m_flavs[1] && isrhandler->AllowSwap(m_flavs[0],m_flavs[1])) m_symfac*=(m_issymfac=2.0); m_name+=pi.m_addname; m_resname=m_name; } std::string Process_Base::BaseName (const std::string &name,const std::string &addname) { std::string fname(name); size_t len(addname.length()); if (len) { size_t apos(fname.rfind(addname)); if (apos!=std::string::npos) fname=fname.erase(apos,len); } size_t pos=fname.find("EW"); if (pos!=std::string::npos) fname=fname.substr(0,pos-2); pos=fname.find("QCD"); if (pos!=std::string::npos) fname=fname.substr(0,pos-2); return fname; } std::string Process_Base::GenerateName(const Subprocess_Info &info) { std::string name(info.m_fl.IDName()); if (info.m_fl.Kfcode()==kf_quark && info.m_fl.IsAnti()) name+="b"; if (info.m_ps.empty()) return name; name+="["+GenerateName(info.m_ps.front()); for (size_t i(1);i &legs,FMMap *const fmm) { if (legs.empty()) return; ATOOLS::Flavour heaviest(kf_photon); for (size_t i(0);iFlav().Mass()>heaviest.Mass()) heaviest=legs[i]->Flav(); else if (legs[i]->Flav().Mass()==heaviest.Mass() && !legs[i]->Flav().IsAnti()) heaviest=legs[i]->Flav(); } std::sort(legs.begin(),legs.end(),Order_Flavour(fmm)); } void Process_Base::SortFlavours (Cluster_Amplitude *const ampl,const int mode) { FMMap fmm; DecayInfo_Vector cs; ClusterLeg_Vector il, fl; std::vector dec(ampl->Legs().size(),0); std::map dmap; for (size_t j(0);jDecays().size();++j) { Decay_Info *cdi(ampl->Decays()[j]); size_t did(cdi->m_id), ndc(IdCount(did)); for (size_t i(ampl->NIn());iLeg(i)->Id()) { dec[i]=1; dmap[cdi->m_id].push_back(ampl->Leg(i)); } bool core(true); for (size_t i(0);iDecays().size();++i) if ((ampl->Decays()[i]->m_id&did) && IdCount(ampl->Decays()[i]->m_id)>ndc) { core=false; break; } if (!core) continue; int kfc(cdi->m_fl.Kfcode()); if (fmm.find(kfc)==fmm.end()) fmm[kfc]=0; if (cdi->m_fl.IsFermion()) { fmm[kfc]+=10; if (!cdi->m_fl.IsAnti()) fmm[kfc]+=10; } cs.push_back(cdi); } for (size_t i(0);iLegs().size();++i) if (iNIn()) { ampl->Leg(i)->SetFlav(ampl->Leg(i)->Flav().Bar()); il.push_back(ampl->Leg(i)); int kfc(ampl->Leg(i)->Flav().Kfcode()); if (fmm.find(kfc)==fmm.end()) fmm[kfc]=0; if (ampl->Leg(i)->Flav().IsFermion()) { fmm[kfc]+=10; if (!ampl->Leg(i)->Flav().IsAnti()) fmm[kfc]+=10; } } else { if (dec[i]) continue; fl.push_back(ampl->Leg(i)); int kfc(ampl->Leg(i)->Flav().Kfcode()); if (fmm.find(kfc)==fmm.end()) fmm[kfc]=0; if (ampl->Leg(i)->Flav().IsFermion()) ++fmm[kfc]; } if (mode&1) SortFlavours(il,s_usefmm?&fmm:NULL); for (size_t i(0);iCreateLeg(Vec4D(),cs[i]->m_fl,ColorID(),cs[i]->m_id); fl.push_back(ampl->Legs().back()); } SortFlavours(fl,s_usefmm?&fmm:NULL); if (cs.size()) { cs=ampl->Decays(); std::sort(cs.begin(),cs.end(),Order_NDecay()); while (fl.size()Legs().size()-ampl->NIn()) for (ClusterLeg_Vector::iterator fit(fl.begin());fit!=fl.end();++fit) if (dmap.find((*fit)->Id())!=dmap.end()) { ClusterLeg_Vector cl(dmap[(*fit)->Id()]); size_t inc(0), ncd(IdCount((*fit)->Id())); for (size_t i(0);im_id)m_id&(*fit)->Id()) && (cs[i]->m_id&inc)==0) { ampl->CreateLeg(Vec4D(),cs[i]->m_fl,ColorID(),cs[i]->m_id); for (ClusterLeg_Vector::iterator cit(cl.begin());cit!=cl.end();) if (!((*cit)->Id()&cs[i]->m_id)) ++cit; else cit=cl.erase(cit); cl.push_back(ampl->Legs().back()); inc|=cs[i]->m_id; } SortFlavours(cl,s_usefmm?&fmm:NULL); (*fit)->Delete(); fit=fl.erase(fit); fl.insert(fit,cl.begin(),cl.end()); ampl->Legs().pop_back(); break; } } for (size_t i(0);iNIn();++i) { il[i]->SetFlav(il[i]->Flav().Bar()); ampl->Legs()[i]=il[i]; } for (size_t i(ampl->NIn());iLegs().size();++i) ampl->Legs()[i]=fl[i-ampl->NIn()]; } std::string Process_Base::GenerateName(const Cluster_Amplitude *ampl) { char nii[3], nfi[3]; if (sprintf(nii,"%i",(int)ampl->NIn())<=0) THROW(fatal_error,"Conversion error"); if (sprintf(nfi,"%i",(int)(ampl->Legs().size()-ampl->NIn()))<=0) THROW(fatal_error,"Conversion error"); std::string name(nii+std::string("_")+nfi); for (size_t i(0);iNIn();++i) name+="__"+ampl->Leg(i)->Flav().Bar().IDName(); DecayInfo_Vector decs(ampl->Decays()); std::sort(decs.begin(),decs.end(),Order_NDecay()); for (size_t i(ampl->NIn());iLegs().size();++i) { std::string op, cl; for (size_t j(0);jm_id)); if (ampl->Leg(i)->Id()==(1<m_fl)+"["; else if (ampl->Leg(i)->Id()==(1<Leg(i)->Flav().IDName()+cl; } return name; } std::string Process_Base::GenerateName(const NLO_subevt *sub,const size_t &nin) { char nii[3], nfi[3]; if (sprintf(nii,"%i",(int)nin)<=0) THROW(fatal_error,"Conversion error"); if (sprintf(nfi,"%i",(int)(sub->m_n-nin))<=0) THROW(fatal_error,"Conversion error"); std::string name(nii+std::string("_")+nfi); for (size_t i(0);im_n;++i) name+="__"+sub->p_fl[i].IDName(); return name; } void Process_Base::SetGenerator(ME_Generator_Base *const gen) { p_gen=gen; } void Process_Base::SetShower(PDF::Shower_Base *const ps) { p_shower=ps; } void Process_Base::SetNLOMC(PDF::NLOMC_Base *const mc) { p_nlomc=mc; } void Process_Base::FillOnshellConditions() { if (!Selector()) return; Subprocess_Info info(m_pinfo.m_ii); info.Add(m_pinfo.m_fi); for(size_t i=0;im_osd) Selector()->AddOnshellCondition (m_decins[i]->m_id,sqr(m_decins[i]->m_fl.Mass())); } void Process_Base::FillAmplitudes(std::vector& amp, std::vector >& cols) { THROW(fatal_error, "Virtual function called."); } void Process_Base::SetSelector(const Selector_Key &key) { if (IsMapped()) return; if (p_selector==NULL) p_selector = new Combined_Selector(this); p_selector->Initialize(key); } void Process_Base::SetCaller(Process_Base *const proc) { p_caller=proc; } bool Process_Base::Trigger(const Vec4D_Vector &p) { if (IsMapped() && LookUp()) return Selector()->Result(); return Selector()->Trigger(p); } NLO_subevtlist *Process_Base::GetSubevtList() { return NULL; } NLO_subevtlist *Process_Base::GetRSSubevtList() { return NULL; } void Process_Base::InitCuts(Cut_Data *const cuts) { cuts->Init(m_nin,m_flavs); } void Process_Base::BuildCuts(Cut_Data *const cuts) { if (IsMapped() && LookUp()) return; Selector()->BuildCuts(cuts); } void Process_Base::SetRBMap(Cluster_Amplitude *ampl) { } void Process_Base::InitPSHandler (const double &maxerr,const std::string eobs,const std::string efunc) { p_int->SetPSHandler(std::make_shared(p_int, maxerr)); if (eobs!="") p_int->PSHandler()->SetEnhanceObservable(eobs); if (efunc!="") p_int->PSHandler()->SetEnhanceFunction(efunc); } double Process_Base::LastPlus() { if (IsGroup()) { double last=0.0; for (size_t i(0);iLastPlus(); return last; } double last(Last()); return last>0.0?last:0.0; } double Process_Base::LastMinus() { if (IsGroup()) { double last=0.0; for (size_t i(0);iLastMinus(); return last; } double last(Last()); return last<0.0?last:0.0; } void Process_Base::FillProcessMap(NLOTypeStringProcessMap_Map *apmap) { p_apmap=apmap; if (IsGroup()) { for (size_t i(0);iFillProcessMap(apmap); } else { nlo_type::code nlot(m_pinfo.m_fi.m_nlotype); std::string fname(m_name); size_t pos=m_pinfo.m_addname.length()? fname.find(m_pinfo.m_addname):std::string::npos; if (pos!=std::string::npos) fname=fname.substr(0,pos); pos=fname.find("EW"); if (pos!=std::string::npos) fname=fname.substr(0,pos-2); pos=fname.find("QCD"); if (pos!=std::string::npos) fname=fname.substr(0,pos-2); if (nlot&nlo_type::vsub) nlot=nlo_type::vsub; if (nlot&nlo_type::rsub) nlot=nlo_type::rsub; if (apmap->find(nlot)==apmap->end()) (*apmap)[nlot] = new StringProcess_Map(); StringProcess_Map *cmap((*apmap)[nlot]); if (cmap->find(fname)!=cmap->end()) { if (msg_LevelIsDebugging()) { Process_Base* old = (*cmap)[fname]; msg_Out()< "<SetMCMode(mcmode); return cmcmode; } size_t Process_Base::SetClusterMode(const size_t cmode) { size_t ccmode(m_cmode); m_cmode=cmode; if (IsGroup()) for (size_t i(0);iSetClusterMode(cmode); return ccmode; } void Process_Base::SetSProc(Process_Base *sproc) { p_sproc=sproc; if (IsGroup()) for (size_t i(0);iSetSProc(sproc); } void Process_Base::SetBBarMC(BBar_Multi_Channel *mc) { p_mc=mc; if (IsGroup()) for (size_t i(0);iSetBBarMC(mc); } int Process_Base::NaiveMapping(Process_Base *proc) const { DEBUG_FUNC(Name()<<" -> "<Name()); const Vertex_Table *vt(s_model->VertexTable()); std::map fmap; std::vector curf(m_flavs); for (size_t i(0);im_flavs[i]; for (std::map::const_iterator fit(fmap.begin());fit!=fmap.end();++fit) DEBUG_VAR(fit->first<<" -> "<second); for (size_t i(0);ifind(cf)->second); const Vertex_List &vlm(vt->find(mf)->second); DEBUG_VAR(cf<<" "<Compare(vlc[j])==0) { msg_Indent(); for (int n=1;nNLegs();++n) { std::map:: const_iterator cit(fmap.find(vlc[j]->in[n])); if (cit==fmap.end()) { DEBUG_VAR(vlc[j]->in[n]<<" -> "<in[n]); if (vlc[j]->in[n].Mass()!=vlm[k]->in[n].Mass() || vlc[j]->in[n].Width()!=vlm[k]->in[n].Width()) { msg_Debugging()<<"m_"<in[n] <<" = "<in[n].Mass() <<" / m_"<in[n] <<" = "<in[n].Mass()<<"\n"; msg_Debugging()<<"w_"<in[n] <<" = "<in[n].Width() <<" / w_"<in[n] <<" = "<in[n].Width()<<"\n"; return 0; } fmap[vlc[j]->in[n]]=vlm[k]->in[n]; curf.push_back(vlc[j]->in[n]); } else if (cit->second!=vlm[k]->in[n]) { DEBUG_VAR(cit->second<<" "<in[n]); return 0; } } DEBUG_VAR(*vlc[j]); DEBUG_VAR(*vlm[k]); match=true; break; } } if (!match) return 0; } } DEBUG_VAR("OK"); return 1; } std::string Process_Base::ShellName(std::string name) const { if (name.length()==0) name=m_name; for (size_t i(0);(i=name.find('-',i))!=std::string::npos;name.replace(i,1,"m")); for (size_t i(0);(i=name.find('+',i))!=std::string::npos;name.replace(i,1,"p")); for (size_t i(0);(i=name.find('~',i))!=std::string::npos;name.replace(i,1,"x")); for (size_t i(0);(i=name.find('(',i))!=std::string::npos;name.replace(i,1,"_")); for (size_t i(0);(i=name.find(')',i))!=std::string::npos;name.replace(i,1,"_")); for (size_t i(0);(i=name.find('[',i))!=std::string::npos;name.replace(i,1,"I")); for (size_t i(0);(i=name.find(']',i))!=std::string::npos;name.replace(i,1,"I")); return name; } const ATOOLS::Vec4D_Vector & Process_Base::Momenta() const { return p_int->Momenta(); }