#include "ATOOLS/Org/CXXFLAGS_PACKAGES.H" #include "MODEL/Main/Model_Base.H" #include "MODEL/Main/Running_AlphaS.H" #include "MODEL/Main/Running_AlphaQED.H" #include "PHASIC++/Main/Phase_Space_Handler.H" #include "PHASIC++/Process/Process_Base.H" #include "PHASIC++/Process/External_ME_Args.H" #include "ATOOLS/Org/Message.H" #include "ATOOLS/Org/MyStrStream.H" #include "ATOOLS/Org/Library_Loader.H" #include "ATOOLS/Org/Run_Parameter.H" #include #include #include "Recola_Interface.H" using namespace PHASIC; using namespace MODEL; using namespace ATOOLS; using namespace std; std::string Recola::Recola_Interface::s_recolaprefix = std::string(""); bool Recola::Recola_Interface::s_ignore_model = false; bool Recola::Recola_Interface::s_exit_on_error= true; double Recola::Recola_Interface::s_light_fermion_threshold=0.1; size_t Recola::Recola_Interface::s_recolaProcIndex = 0; bool Recola::Recola_Interface::s_processesGenerated = false; size_t Recola::Recola_Interface::s_getPDF_default = 0; size_t Recola::Recola_Interface::s_default_flav = 6; size_t Recola::Recola_Interface::s_fixed_flav = 0; double Recola::Recola_Interface::s_default_alphaqcd = 0; double Recola::Recola_Interface::s_default_scale = 0; std::vector Recola::Recola_Interface::s_pdfmass(6); bool Recola::Recola_Interface::s_compute_poles = false; size_t Recola::Recola_Interface::s_vmode = 0; int Recola::Recola_Interface::s_ewscheme = 3; int Recola::Recola_Interface::s_amptype = 1; std::map Recola::Recola_Interface::s_procmap; std::map Recola::Recola_Interface::s_asscontribs; std::map Recola::Recola_Interface::s_interference; size_t Recola::Recola_Interface::s_doint = 1; Recola::Recola_Interface::Recola_Interface() : ME_Generator_Base("Recola") {RegisterDefaults();} Recola::Recola_Interface::~Recola_Interface() {} std::string Recola::Recola_Interface::particle2Recola(const int p){ if(p==1) return "d"; if(p==-1) return "d~"; if(p==2) return "u"; if(p==-2) return "u~"; if(p==3) return "s"; if(p==-3) return "s~"; if(p==4) return "c"; if(p==-4) return "c~"; if(p==5) return "b"; if(p==-5) return "b~"; if(p==6) return "t"; if(p==-6) return "t~"; if(p==11) return "e-"; if(p==-11)return "e+"; if(p==12) return "nu_e"; if(p==-12)return "nu_e~"; if(p==13) return "mu-"; if(p==-13)return "mu+"; if(p==14) return "nu_mu"; if(p==-14)return "nu_mu~"; if(p==15) return "tau-"; if(p==-15)return "tau+"; if(p==16) return "nu_tau"; if(p==-16)return "nu_tau~"; if(p==21) return "g"; if(p==22) return "A"; if(p==23) return "Z"; if(p==24) return "W+"; if(p==-24)return "W-"; if(p==25) return "H"; THROW(fatal_error, "Unknown particle id "+ToString(p)); } std::string Recola::Recola_Interface::particle2Recola(const std::string p){ if(p=="d") return "d"; if(p=="db") return "d~"; if(p=="u") return "u"; if(p=="ub") return "u~"; if(p=="s") return "s"; if(p=="sb") return "s~"; if(p=="c") return "c"; if(p=="cb") return "c~"; if(p=="b") return "b"; if(p=="bb") return "b~"; if(p=="t") return "t"; if(p=="tb") return "t~"; if(p=="e-") return "e-"; if(p=="e+") return "e+"; if(p=="ve") return "nu_e"; if(p=="veb") return "nu_e~"; if(p=="mu-") return "mu-"; if(p=="mu+") return "mu+"; if(p=="vmu") return "nu_mu"; if(p=="vmub") return "nu_mu~"; if(p=="tau-") return "tau-"; if(p=="tau+") return "tau+"; if(p=="vtau") return "nu_tau"; if(p=="vtaub") return "nu_tau~"; if(p=="G") return "g"; if(p=="P") return "A"; if(p=="Z") return "Z"; if(p=="W+") return "W+"; if(p=="W-") return "W-"; if(p=="h0") return "H"; THROW(fatal_error, "Unknown particle id "+ToString(p)); } std::string Recola::Recola_Interface::process2Recola(const Flavour_Vector& fl) { std::string process = particle2Recola(fl[0].IDName()) + " " + particle2Recola(fl[1].IDName()) + " -> "; for(size_t i=2; igen.Variable("SHERPA_CPP_PATH")+"/Process/Recola"; s_recolaprefix = string(((var=getenv("RECOLA_PREFIX"))==NULL ? s_recolaprefix : var)); struct stat st; if(stat(s_recolaprefix.c_str(), &st) != 0) s_recolaprefix = RECOLA_PREFIX; s["RECOLA_PREFIX"].SetDefault(s_recolaprefix); s_recolaprefix = s["RECOLA_PREFIX"].Get(); } bool Recola::Recola_Interface::Initialize(MODEL::Model_Base *const model, BEAM::Beam_Spectra_Handler *const beam, PDF::ISR_Handler *const isr) { msg_Info()<<"Initialising Recola generator from "<(); if (s_ignore_model) { msg_Info()<(); if(recolaVerbosity<0 || recolaVerbosity >2) THROW(fatal_error, "Invalid value for RECOLA_VERBOSITY"); set_print_level_squared_amplitude_rcl(recolaVerbosity); set_print_level_amplitude_rcl(recolaVerbosity); set_print_level_correlations_rcl(recolaVerbosity); string recolaOutput = s["RECOLA_OUTPUT"].Get(); s_amptype = s["RECOLA_AMPTYPE"].Get(); set_output_file_rcl(recolaOutput.c_str()); s_vmode = s["RECOLA_VMODE"].Get(); msg_Tracking()<(); if (s_compute_poles) { msg_Info()<Name() != "SM") THROW(not_implemented, "ONLY Standard Model so far supported in RECOLA"); bool recolaOnShellZW = s["RECOLA_ONSHELLZW"].Get(); // set particle masses/widths if(recolaOnShellZW != 0){ set_onshell_mass_z_rcl(Flavour(kf_Z).Mass(),Flavour(kf_Z).Width()); set_onshell_mass_w_rcl(Flavour(kf_Wplus).Mass(),Flavour(kf_Wplus).Width()); } else{ set_pole_mass_z_rcl(Flavour(kf_Z).Mass(),Flavour(kf_Z).Width()); set_pole_mass_w_rcl(Flavour(kf_Wplus).Mass(),Flavour(kf_Wplus).Width()); } set_pole_mass_h_rcl(Flavour(kf_h0).Mass(),Flavour(kf_h0).Width()); set_pole_mass_electron_rcl(Flavour(kf_e).Mass()); set_pole_mass_muon_rcl(Flavour(kf_mu).Mass(),Flavour(kf_mu).Width()); set_pole_mass_tau_rcl(Flavour(kf_tau).Mass(),Flavour(kf_tau).Width()); set_pole_mass_up_rcl(Flavour(kf_u).Mass()); set_pole_mass_down_rcl(Flavour(kf_d).Mass()); set_pole_mass_strange_rcl(Flavour(kf_s).Mass()); set_pole_mass_charm_rcl(Flavour(kf_c).Mass(),Flavour(kf_c).Width()); set_pole_mass_bottom_rcl(Flavour(kf_b).Mass(),Flavour(kf_b).Width()); set_pole_mass_top_rcl(Flavour(kf_t).Mass(),Flavour(kf_t).Width()); s_light_fermion_threshold = s["RECOLA_LIGHT_FERMION_THRESHOLD"].Get(); set_light_fermions_rcl(s_light_fermion_threshold); set_delta_ir_rcl(0.0,M_PI*M_PI/6.0); // adapts the conventions from COLLIER to Catani-Seymour PDF::PDF_Base *pdf=isr->PDF(0); auto pdfnf = -1; auto cmass = 0.0; auto bmass = 0.0; auto tmass = 0.0; bool hadronic_beam1 = beam->GetBeam(0)->Beam().IsHadron(); bool hadronic_beam2 = beam->GetBeam(1)->Beam().IsHadron(); if(hadronic_beam1!=hadronic_beam2) THROW(not_implemented,"Recola interface cannot handle DIS yet."); bool hadronic_beam = hadronic_beam1; if (hadronic_beam) { pdfnf=pdf->ASInfo().m_flavs.size(); s_default_alphaqcd=pdf->ASInfo().m_asmz; s_default_scale=pdf->ASInfo().m_mz2; s_default_flav=pdfnf; if (pdfnf>10) pdfnf-=10; if (pdfnf==-1) pdfnf=6; cmass=pdf->ASInfo().m_flavs[3].m_mass; bmass=pdf->ASInfo().m_flavs[4].m_mass; tmass=pdf->ASInfo().m_flavs[5].m_mass; if(pdf->ASInfo().m_flavs.size()<6) tmass=Flavour(kf_t).Mass(); } else { pdfnf = MODEL::as->Nf(1.e20); s_default_alphaqcd=MODEL::as->AsMZ(); s_default_scale=Flavour{kf_Z}.Mass(); s_default_flav=pdfnf; const auto thresholds = MODEL::as->Thresholds(0.0, 1e20); tmass = sqrt(thresholds[thresholds.size() - 1]); bmass = sqrt(thresholds[thresholds.size() - 2]); cmass = sqrt(thresholds[thresholds.size() - 3]); } if (hadronic_beam) { for (int i=0; i<3; i++){ if (iASInfo().m_flavs[i].m_thres; } } else { for (int i{0}; i < 3; ++i) s_pdfmass[i] = Flavour{i+1}.Mass(1); } s_pdfmass[3]=cmass; s_pdfmass[4]=bmass; s_pdfmass[5]=tmass; set_alphas_masses_rcl(cmass,bmass,tmass, Flavour(kf_c).Width(),Flavour(kf_b).Width(), Flavour(kf_t).Width()); s_fixed_flav=Recola_Interface::GetDefaultFlav()+10; return true; } // This function is specific for LO or Born processes since they read // settings from External_ME_Args... int Recola::Recola_Interface::RegisterProcess(const External_ME_Args& args, const int& amptype) { DEBUG_FUNC(""); increaseProcIndex(); msg_Debugging()<<"Recola_Interface::RegisterProcess called\n"; int procIndex(getProcIndex()); msg_Debugging()<<"ProcIndex = " <(); if (cc>=0) split_collier_cache_rcl(procIndex,cc); select_gs_power_LoopAmpl_rcl(procIndex,args.m_orders[0]); } else select_gs_power_BornAmpl_rcl(procIndex,args.m_orders[0]); return procIndex; } size_t Recola::Recola_Interface::RegisterProcess(const Process_Info& pi, int amptype) { DEBUG_FUNC(""); increaseProcIndex(); msg_Debugging()<<"Recola_Interface::RegisterProcess called\n"; int procIndex(getProcIndex()); msg_Debugging()<<"ProcIndex = " <(); // set collier caching level int cc=s["RECOLA_COLLIER_CACHE"].Get(); if (cc>=0) split_collier_cache_rcl(procIndex,cc); // find out whether we need multiple orders or not s_asscontribs[procIndex]=pi.m_fi.m_asscontribs; // if we only need specific orders, set them if (s_asscontribs[procIndex]==asscontrib::none) { // unset all powers of the amplitude unselect_all_gs_powers_BornAmpl_rcl(procIndex); unselect_all_gs_powers_LoopAmpl_rcl(procIndex); int quarkcount(0), gluoncount(0); int tempQCD(pi.m_maxcpl[0]), tempEW(pi.m_maxcpl[1]); if(pi.m_fi.m_nlotype==nlo_type::loop){ // Check whether for this process any interference // diagram is present if (s_doint){ Flavour_Vector inflavs(pi.m_ii.GetExternal()); Flavour_Vector outflavs(pi.m_fi.GetExternal()); for (int i=0; i=4) && (pi.m_maxcpl[0]>=2)){ s_interference[procIndex]=true; } if ((pi.m_fi.m_nlocpl[0]==1) && (quarkcount>=4) && (pi.m_maxcpl[1]>=2)){ s_interference[procIndex]=true; tempQCD-=1; } tempEW=quarkcount-2-tempQCD; } // If interference is present set orders properly if (s_interference[procIndex]){ int maxBqcd, minBqcd; if ((tempQCD+2*pi.m_fi.m_nlocpl[0])>tempEW) maxBqcd=pi.m_maxcpl[0]+tempEW-pi.m_fi.m_nlocpl[0]; else maxBqcd=pi.m_maxcpl[0]+tempQCD+pi.m_fi.m_nlocpl[0]; if ((tempEW+2*pi.m_fi.m_nlocpl[1])>tempQCD) minBqcd=pi.m_maxcpl[0]-tempQCD-pi.m_fi.m_nlocpl[0]; else minBqcd=pi.m_maxcpl[0]-tempEW-pi.m_fi.m_nlocpl[0]-2*pi.m_fi.m_nlocpl[1]; while (quarkcount>=2 && maxBqcd>=minBqcd){ select_gs_power_LoopAmpl_rcl(procIndex,2.*pi.m_maxcpl[0]-maxBqcd); select_gs_power_BornAmpl_rcl(procIndex,maxBqcd); quarkcount-=2; maxBqcd-=2; } } // If there is no interference set orders normally checking for // EW or QCD NLO else{ // now set the requested powers for the amplitude if (pi.m_fi.m_nlocpl[0]==1) { double borngspower=pi.m_maxcpl[0]-pi.m_fi.m_nlocpl[0]; double loopgspower=pi.m_maxcpl[0]+pi.m_fi.m_nlocpl[0]; msg_Debugging()<<"QCD Tree gs-power = "<(); ew_scheme::code ewrenscheme = s["EW_REN_SCHEME"].Get(); if (ewscheme!=ewrenscheme) THROW(fatal_error,"Inconsistent input scheme."); switch (ewscheme) { case 1: // use_alpha0_scheme_and_set_alpha_rcl(AlphaQED()); use_alpha0_scheme_rcl(alpha); break; case 2: // use_alphaz_scheme_and_set_alpha_rcl(AlphaQED()); use_alphaz_scheme_rcl(alpha); break; case 3: use_gfermi_scheme_and_set_alpha_rcl(alpha); break; default: msg_Error()<<"The EW scheme "<0 && fflav<10) nlight=fflav; else { if (default_flavscheme>10) nlight=Recola_Interface::PDFnf(muR2,default_flavscheme-10); if (default_flavscheme==-1) nlight=-1; if (default_flavscheme==-2 || default_flavscheme==0) { if (Flavour(kf_c).Mass()!=0) nlight=3; else if (Flavour(kf_b).Mass()!=0) nlight=4; else if (Flavour(kf_t).Mass()!=0) nlight=5; else { msg_Out()<<"WARNING: 6 light flavours detected.\n"; nlight=6; } } } if (nlight==0) { msg_Error()<6) { msg_Error()< &asscontribs) { vector pp(4*momenta.size()); const int NN = momenta.size(); double fpp[NN][4]; for (int i=0; i=1) get_squared_amplitude_rcl(id,boqcd-1,"LO",asscontribs[1]); msg_Debugging()<<"... BsubLO1="<2)) THROW(fatal_error,"Inconsistent state."); msg_Debugging()<<"Getting BsubLO2 ..."<=2) get_squared_amplitude_rcl(id,boqcd-2,"LO",asscontribs[2]); msg_Debugging()<<"... BsubLO2="<3)) THROW(fatal_error,"Inconsistent state."); msg_Debugging()<<"Getting BsubLO3 ..."<=3) get_squared_amplitude_rcl(id,boqcd-3,"LO",asscontribs[3]); msg_Debugging()<<"... BsubLO3="< "< "<:: operator()(const PHASIC::ME_Generator_Key &key) const { return new Recola::Recola_Interface(); } void ATOOLS::Getter:: PrintInfo(std::ostream &str,const std::size_t width) const { str<<"Interface to the Recola loop ME generator"; }