#include "PHASIC++/Scales/MINLO_Scale_Setter.H" #include "PHASIC++/Process/Process_Base.H" #include "PHASIC++/Process/Single_Process.H" #include "PHASIC++/Main/Process_Integrator.H" #include "MODEL/Main/Running_AlphaS.H" #include "PDF/Main/PDF_Base.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Org/Exception.H" #include "ATOOLS/Org/Scoped_Settings.H" #include "ATOOLS/Org/Data_Reader.H" using namespace PHASIC; using namespace ATOOLS; DECLARE_GETTER(MINLO_Scale_Setter,"MINLO", Scale_Setter_Base,Scale_Setter_Arguments); Scale_Setter_Base *ATOOLS::Getter :: operator()(const Scale_Setter_Arguments &args) const { return new MINLO_Scale_Setter(args); } void ATOOLS::Getter:: PrintInfo(std::ostream &str,const size_t width) const { str<<"minlo scale scheme"; } MINLO_Scale_Setter::MINLO_Scale_Setter (const Scale_Setter_Arguments &args): Scale_Setter_Base(args), m_tagset(this), p_ampl(NULL), p_vampl(NULL), p_isr{ p_proc->Integrator()->ISR() } { RegisterDefaults(); Settings& s = Settings::GetMainSettings(); std::string tag(args.m_scale), core; m_nproc=p_proc->Info().Has(nlo_type::real) || p_proc->Info().Has(nlo_type::rsub) || p_proc->Info().Has(nlo_type::loop) || p_proc->Info().Has(nlo_type::vsub); size_t pos(tag.find('[')); if (pos!=std::string::npos) { tag=tag.substr(pos+1); pos=tag.find(']'); if (pos==std::string::npos) THROW(fatal_error,"Invalid scale '"+args.m_scale+"'"); core=tag.substr(0,pos); tag=tag.substr(pos+1); } if (tag.find('{')==std::string::npos && tag.find('}')==std::string::npos) tag+="{MU_F2}{MU_R2}{MU_Q2}"; while (true) { size_t pos(tag.find('{')); if (pos==std::string::npos) { if (!m_calcs.empty()) break; else { THROW(fatal_error,"Invalid scale '"+args.m_scale+"'"); } } tag=tag.substr(pos+1); pos=tag.find('}'); if (pos==std::string::npos) THROW(fatal_error,"Invalid scale '"+args.m_scale+"'"); std::string ctag(tag.substr(0,pos)); tag=tag.substr(pos+1); m_calcs.push_back(new Algebra_Interpreter()); m_calcs.back()->AddFunction(MODEL::as->GetAIGMeanFunction()); m_calcs.back()->SetTagReplacer(&m_tagset); if (m_calcs.size()==1) m_tagset.SetCalculator(m_calcs.back()); SetScale(ctag,*m_calcs.back()); } m_scale.resize(Max(m_scale.size(),m_calcs.size())); SetCouplings(); Scoped_Settings metssettings{ s["MINLO"] }; m_noutmin = metssettings["NOUT_MIN"].Get(); m_cmode = metssettings["CLUSTER_MODE"].Get(); m_hqmode = metssettings["HQ_MODE"].Get(); m_order = metssettings["FORCE_ORDER"].Get(); m_orderrs = metssettings["ORDER_RS"].Get(); m_usecomb = metssettings["USE_COMBINABLE"].Get(); m_usepdfinfo = metssettings["USE_PDFINFO"].Get(); m_nlocpl = metssettings["NLO_COUPLING_MODE"].Get(); m_mufmode = metssettings["MUF_VARIATION_MODE"].Get(); m_bumode = metssettings["BACKUP_MODE"].Get(); m_murmode = metssettings["MUR_MODE"].Get(); m_dr = metssettings["DELTA_R"].Get(); m_muf2min = metssettings["MUF2_MIN"].Get(); if (core == "") { core = s["CORE_SCALE"].GetScalarWithOtherDefault("VAR{H_TM2/4}"); } if (metssettings["ALLOW_CORE"].IsCustomised()) { const auto cores = metssettings["ALLOW_CORE"].GetVector(); msg_Debugging()<(); m_rsf=ToType(rpa->gen.Variable("RENORMALIZATION_SCALE_FACTOR")); if (m_rsf!=1.0) msg_Debugging()<(rpa->gen.Variable("FACTORIZATION_SCALE_FACTOR")); if (m_fsf!=1.0) msg_Debugging()<PDF(0)->Q2Min()); s.DeclareVectorSettingsWithEmptyDefault({ "ALLOW_CORE" }); } bool MINLO_Scale_Setter::UpdateScale(const ATOOLS::Variation_Parameters &var) { DEBUG_FUNC("ren scale fac = "<NIn();++i) m_p[i]=-m_p[i]; if (p_ampl) p_ampl->Delete(); m_rproc=p_proc->Caller()->Info().Has(nlo_type::real); m_vproc=p_proc->Caller()->Info().Has(nlo_type::loop) || p_proc->Caller()->Info().Has(nlo_type::vsub); m_f=p_proc->Caller()->Flavours(); for (size_t i(0);iCaller()->NIn();++i) m_f[i]=m_f[i].Bar(); DEBUG_FUNC(p_proc->Name()<<" from "<Caller()->Name()<<", R="< &trials(alltrials[ampl->Legs().size()-(m_nin+m_noutmin)]); MCS_Params ckw(0,0,0,kf_none); msg_Debugging()<<"Weights: {\n"; for (size_t i(0);iLegs().size();++i) { msg_Indent(); Cluster_Leg *li(ampl->Leg(i)); for (size_t j(Max((size_t)2,i+1));jLegs().size();++j) { Cluster_Leg *lj(ampl->Leg(j)); Flavour_Vector cf; if (m_usecomb) { if (!proc->Combinable(li->Id(),lj->Id())) continue; cf=proc->CombinedFlavour(li->Id()+lj->Id()); } else { if (!li->Flav().Strong() || !lj->Flav().Strong()) continue; if (m_hqmode==1 && (li->Flav().Mass() || lj->Flav().Mass())) continue; if (li->Flav().IsGluon()) cf.push_back(lj->Flav()); else if (lj->Flav().IsGluon()) cf.push_back(li->Flav()); else if (li->Flav()==lj->Flav().Bar()) cf.push_back(kf_gluon); } for (size_t k(0);kLegs().size();++k) { Cluster_Leg *lk(ampl->Leg(k)); if (k!=i && k!=j) { for (size_t f(0);fFlav().Strong() || !li->Flav().Strong() || !lj->Flav().Strong()) continue; if (iNIn() && m_usepdfinfo) { if (p_isr->PDF(i)==NULL) THROW(fatal_error,"No PDF"); if (!p_isr->PDF(i)->Contains(cf[f])) continue; } MCS_Params cs(i,j,k,cf[f]); if (trials.find(cs)!=trials.end()) continue; if (cf[f].IsGluon() && !li->Flav().IsGluon() && li->Flav().Kfcode()>m_nfgsplit && !lj->Flav().IsGluon() && lj->Flav().Kfcode()>m_nfgsplit) { msg_Debugging()<<"Veto flavour: "<Id())<<" & "<Id()) <<" <-> "<Id())<<"\n"; trials.insert(cs); continue; } KT2(ampl,li,lj,lk,cs); if (cs.m_kt2==-1.0) { msg_Debugging()<<"Veto kinematics: "<Id())<<" & "<Id()) <<" <-> "<Id())<<"\n"; trials.insert(cs); continue; } msg_Debugging()<Id())<<" & "<Id()) <<" <-> "<Id())<<" ["<ckw.m_op2) ckw=cs; } } } } } msg_Debugging()<<"}\n"; trials.insert(ckw); if (ckw.m_i==0 && ckw.m_j==0 && ckw.m_k==0) { double kt2core(CoreScale(ampl).m_op); bool ord(true); std::vector > &pops(ops[ampl->Legs().size()-(m_nin+m_noutmin)]); if (m_bumode==1 && (m_order || (m_rproc && ampl->Prev() && ampl->Prev()->Prev()==NULL)) && kt2corePrev(); ampl->DeleteNext(); continue; } else { msg_Debugging()<<"Final configuration:\n"; msg_Debugging()<<*ampl<<"\n"; if (ampl->Legs().size()>m_nin+m_noutmin) ampl->SetFlag(1); if (kt2coreSetFlag(1); while (ampl->Prev()) { ampl=ampl->Prev(); msg_Debugging()<<*ampl<<"\n"; } double muf2(SetScales(p_vampl=ampl,m_vmode=mode)); return muf2; } } msg_Debugging()<<"Cluster "<Leg(ckw.m_i)->Id()) <<" & "<Leg(ckw.m_j)->Id()) <<" <-> "<Leg(ckw.m_k)->Id()) <<" => "< > &cops(ops[ampl->Legs().size()-(m_nin+m_noutmin+1)]), &pops(ops[ampl->Legs().size()-(m_nin+m_noutmin)]); cops=pops; size_t sid(ampl->Leg(ckw.m_i)->Id()|ampl->Leg(ckw.m_j)->Id()); size_t lmin(100), li(0); for (size_t i(0);iPrev()==NULL) cops[li].second=0.0; msg_Debugging()<<"set last k_T = "<Prev() && ampl->Prev()->Prev()==NULL)) && cops[li].secondSetFlag(1); CoreScale(ampl); msg_Debugging()<<"Final configuration:\n"; msg_Debugging()<<*ampl<<"\n"; while (ampl->Prev()) { ampl=ampl->Prev(); msg_Debugging()<<*ampl<<"\n"; } double muf2(SetScales(p_vampl=ampl,m_vmode=mode)); return muf2; } ampl->SetKT2(ckw.m_kt2); ampl->SetMu2(ckw.m_kt2); ampl=ampl->InitNext(); ampl->CopyFrom(ampl->Prev()); if (!Combine(*ampl,ckw)) { msg_Debugging()<<"combine failed\n"; ampl=ampl->Prev(); ampl->DeleteNext(); continue; } if (m_cores.size()) { bool found(true); for (size_t i(0);iLegs().size()!=m_cores[i].size()) continue; found=false; bool match(true); for (size_t j(0);jLegs().size();++j) if (!m_cores[i][j].Includes(ampl->Leg(j)->Flav())) { msg_Debugging()<Leg(j)->Flav()<<" does not match " <Prev(); ampl->DeleteNext(); continue; } } ampl->SetOrderQCD(ampl->OrderQCD()-1); } THROW(fatal_error,"Invalid amplitude"); return 0.0; } PDF::Cluster_Param MINLO_Scale_Setter::CoreScale(Cluster_Amplitude *const ampl) const { ampl->SetProc(p_proc); PDF::Cluster_Param kt2(p_core->Calculate(ampl)); ampl->SetKT2(kt2.m_kt2); ampl->SetMu2(kt2.m_mu2); for (Cluster_Amplitude *campl(ampl); campl;campl=campl->Prev()) campl->SetMuQ2(kt2.m_op); return kt2; } double MINLO_Scale_Setter::SetScales(Cluster_Amplitude *ampl,const size_t &mode) { m_scale[stp::res]=ampl->MuQ2(); m_scale[stp::fac]=m_q02[0]=m_q02[1]=ampl->KT2(); std::vector scale(p_proc->NOut()+1); msg_Debugging()<<"Setting scales {\n"; double mur2(1.0), as(1.0), ass(0.0), oqcd(0.0); for (size_t idx(2);ampl->Next();++idx,ampl=ampl->Next()) { scale[idx]=Max(ampl->Mu2(),m_rsf*MODEL::as->CutQ2()); scale[idx]=Min(scale[idx],sqr(rpa->gen.Ecms())); if (m_rproc && ampl->Prev()==NULL) { m_scale[stp::fac]=m_q02[0]=m_q02[1]=ampl->Next()->KT2(); continue; } if (ampl->KT2()>m_scale[stp::res]) m_scale[stp::res]=ampl->KT2(); double coqcd(ampl->OrderQCD()-ampl->Next()->OrderQCD()); if (coqcd!=1.0) THROW(fatal_error,"Non-QCD clustering"); double cas(MODEL::as->BoundedAlphaS(m_rsf*scale[idx])); msg_Debugging()<<" \\mu_{"<Mu2(),MODEL::as->CutQ2())); if ((m_bumode&2) && mu2SetKT2(m_scale[stp::res]); ampl->SetMu2(m_scale[stp::res]); mu2=ampl->Mu2(); } if (ampl->OrderQCD()-(m_vproc?1:0)) { int coqcd(ampl->OrderQCD()-(m_vproc?1:0)); double cas(MODEL::as->BoundedAlphaS(m_rsf*mu2)); msg_Debugging()<<" \\mu_{0} = "<Mu2(); else { ass/=oqcd; m_muravg[0]=pow(mur2,1.0/oqcd); m_muravg[1]=MODEL::as->WDBSolve(ass,m_rsf*MODEL::as->CutQ2(), m_rsf*1.01*sqr(rpa->gen.Ecms())); msg_Debugging()<<" as_{NLO} = "<WDBSolve(as,m_rsf*MODEL::as->CutQ2(), m_rsf*1.01*sqr(rpa->gen.Ecms())); if (!IsEqual((*MODEL::as)(mur2),as)) msg_Error()< as = "< "<Calculate()->Get(); m_scale[stp::fac]=m_fsf*Max(m_scale[stp::fac],m_muf2min); msg_Debugging()<Caller()?p_proc->Caller()->Name():"")<<"\n"; ampl->SetMuF2(m_scale[stp::fac]); ampl->SetMuR2(m_scale[stp::ren]); ampl->SetMuQ2(m_scale[stp::res]); while (ampl->Prev()) { ampl=ampl->Prev(); ampl->SetMuF2(m_scale[stp::fac]); ampl->SetMuR2(m_scale[stp::ren]); ampl->SetMuQ2(m_scale[stp::res]); } if (m_mufmode==1) m_q02[1]=m_scale[stp::fac]; return m_scale[stp::fac]; } void MINLO_Scale_Setter::SetScale (const std::string &mu2tag,Algebra_Interpreter &mu2calc) { if (mu2tag=="" || mu2tag=="0") THROW(fatal_error,"No scale specified"); msg_Debugging()<Caller()->Name()<<"' {\n"; msg_Indent(); m_tagset.SetTags(&mu2calc); mu2calc.Interprete(mu2tag); if (msg_LevelIsDebugging()) mu2calc.PrintEquation(); msg_Debugging()<<"}\n"; } bool MINLO_Scale_Setter::Combine (Cluster_Amplitude &l,const MCS_Params &cs) const { int i(cs.m_i), j(cs.m_j), k(cs.m_k); if (i>j) std::swap(i,j); Cluster_Leg *li(ampl.Leg(i)), *lj(ampl.Leg(j)), *lk(ampl.Leg(k)); li->SetFlav(cs.m_fl); li->SetMom(cs.m_pijt); lk->SetMom(cs.m_pkt); for (size_t m(0);mSetK(0); if (i<2) { for (size_t m(0);mSetMom(cs.m_lam*ampl.Leg(m)->Mom()); } } li->SetId(li->Id()+lj->Id()); li->SetK(lk->Id()); std::vector::iterator lit(ampl.Legs().begin()); for (int l(0);lDelete(); ampl.Legs().erase(lit); return true; } void MINLO_Scale_Setter::KT2 (const Cluster_Amplitude *ampl,const Cluster_Leg *li, const Cluster_Leg *lj,const Cluster_Leg *lk,MCS_Params &cs) const { if ((li->Id()&3)<(lj->Id()&3)) std::swap(li,lj); Vec4D pi(li->Mom()), pj(lj->Mom()), pk(lk->Mom()); double mi2=sqr(li->Flav().Mass()), mj2=sqr(lj->Flav().Mass()); double mij2=sqr(cs.m_fl.Mass()), mk2=sqr(lk->Flav().Mass()); if (li->Stat()==3) mi2=pi.Abs2(); if (lj->Stat()==3) mj2=pj.Abs2(); if (lk->Stat()==3) mk2=pk.Abs2(); if (!(m_cmode&1)) {// CSS algorithm if ((li->Id()&3)==0) { if ((lk->Id()&3)==0) { Kin_Args ffp(ClusterFFDipole(mi2,mj2,mij2,mk2,pi,pj,pk,3)); double kt2=cs.m_kt2=2.0*(pi*pj)*ffp.m_z*(1.0-ffp.m_z) -sqr(1.0-ffp.m_z)*mi2-sqr(ffp.m_z)*mj2; if (ffp.m_stat<0) kt2=-1.0; cs.SetParams(kt2,1.0,ffp.m_pi,ffp.m_pk,ffp.m_lam); } else { Kin_Args fip(ClusterFIDipole(mi2,mj2,mij2,mk2,pi,pj,-pk,3)); double kt2=cs.m_kt2=2.0*(pi*pj)*fip.m_z*(1.0-fip.m_z) -sqr(1.0-fip.m_z)*mi2-sqr(fip.m_z)*mj2; Vec4D sum(rpa->gen.PBeam(0)+rpa->gen.PBeam(1)); if ((cs.m_k==0 && fip.m_pk[3]<0.0) || (cs.m_k==1 && fip.m_pk[3]>0.0) || fip.m_pk[0]<0.0 || fip.m_stat<0 || fip.m_pk[0]>rpa->gen.PBeam(cs.m_k)[0]) kt2=-1.0; cs.SetParams(kt2,1.0,fip.m_pi,-fip.m_pk,fip.m_lam); } } else { if ((lk->Id()&3)==0) { Kin_Args ifp(ClusterIFDipole(mi2,mj2,mij2,mk2,0.0,-pi,pj,pk,pk,3|4)); double kt2=cs.m_kt2=-2.0*(pi*pj)*(1.0-ifp.m_y)*(1.0-ifp.m_z); Vec4D sum(rpa->gen.PBeam(0)+rpa->gen.PBeam(1)); if ((cs.m_i==0 && ifp.m_pi[3]<0.0) || (cs.m_i==1 && ifp.m_pi[3]>0.0) || ifp.m_pi[0]<0.0 || ifp.m_stat<0 || ifp.m_pi[0]>rpa->gen.PBeam(cs.m_i)[0]) kt2=-1.0; cs.SetParams(kt2,1.0,-ifp.m_pi,ifp.m_pk,ifp.m_lam); } else { Kin_Args iip(ClusterIIDipole(mi2,mj2,mij2,mk2,-pi,pj,-pk,3)); double kt2=cs.m_kt2=-2.0*(pi*pj)*(1.0-iip.m_z-iip.m_y); Vec4D sum(rpa->gen.PBeam(0)+rpa->gen.PBeam(1)); if ((cs.m_i==0 && iip.m_pi[3]<0.0) || (cs.m_i==1 && iip.m_pi[3]>0.0) || iip.m_pi[0]<0.0 || iip.m_stat<0 || iip.m_pi[0]>rpa->gen.PBeam(cs.m_i)[0]) kt2=-1.0; cs.SetParams(kt2,1.0,-iip.m_pi,-iip.m_pk,iip.m_lam); } } } else {// KT algorithm, E-scheme if ((li->Id()&3)==0) { if (li->Flav().Mass() || lj->Flav().Mass()) { // HQ: massive Durham algorithm double kt2=Min(pi.PSpat2(),pj.PSpat2())* (1.0-pi.CosTheta(pj))/(1.0-cos(m_dr)); cs.SetParams(kt2,m_dr,pi+pj,pk); } else { // LQ: kT algorithm double kt2=Min(pi.PPerp2(),pj.PPerp2())* (sqr(pi.DY(pj))+sqr(pi.DPhi(pj)))/sqr(m_dr); cs.SetParams(kt2,m_dr,pi+pj,pk); } } else { double kt2=pj.PPerp2(); cs.SetParams(kt2,1.0,pi+pj,pk); if ((lk->Id()&3)==0) { cs.m_op2=-1.0; return; } if (m_cmode&8) { double pp(pj.PPlus()), pm(pj.PMinus()); if (pi[3]>0) std::swap(pp,pm); if (m_cmode&16) { if (pm>pp) cs.m_op2=-1.0; } else { if (pp>pm) cs.m_op2*=1.000001; else cs.m_op2/=1.000001; } return; } else if (m_cmode&4) { Vec4D pi0(ampl->First()->Leg(0)->Mom()); Vec4D pk0(ampl->First()->Leg(1)->Mom()); Poincare cms(-pi0-pk0); cms.Boost(pi); cms.Boost(pj); cms.Boost(pk); double y(pj.Y()), ycm(0.5*log(pi[3]/-pk[3])); if (pi[3]<0.0?y-ycm) cs.m_op2=-1.0; return; } else if (m_cmode&2) { Poincare cms(Vec4D(-pi[0]-pk[0],0.0,0.0,-pi[3]-pk[3])); cms.Boost(pi); cms.Boost(pj); } else { Poincare cms(-pi-pk); cms.Boost(pi); cms.Boost(pj); Poincare zax(-pi,Vec4D::ZVEC); zax.Rotate(pi); zax.Rotate(pj); } double pp(pj.PPlus()), pm(pj.PMinus()); if (pi.PPlus()>pi.PMinus()) std::swap(pp,pm); if (pm>pp) cs.m_op2=-1.0; } } }