#include "ATOOLS/Org/CXXFLAGS_PACKAGES.H" #include "ATOOLS/Org/CXXFLAGS.H" #include "MODEL/Main/Model_Base.H" #include "MODEL/Main/Running_AlphaS.H" #include "MODEL/UFO/UFO_Model.H" #include "PHASIC++/Main/Phase_Space_Handler.H" #include "ATOOLS/Org/Message.H" #include "ATOOLS/Org/MyStrStream.H" #include "ATOOLS/Org/Library_Loader.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Org/My_MPI.H" #include "ATOOLS/Org/Scoped_Settings.H" #include #include #include "OpenLoops_Interface.H" using namespace OpenLoops; using namespace PHASIC; using namespace MODEL; using namespace ATOOLS; using namespace std; extern "C" { void ol_welcome(char* str); void ol_set_init_error_fatal(int flag); int ol_get_error(); void ol_getparameter_double(const char* key, double* val); void ol_getparameter_int(const char* key, int* val); void ol_setparameter_double(const char* key, double val); void ol_setparameter_int(const char* key, int val); void ol_setparameter_string(const char* key, const char* val); int ol_register_process(const char* process, int amptype); void ol_start(); void ol_finish(); void ol_evaluate_loop(int id, double* pp, double* m2l0, double* m2l1, double* acc); void ol_evaluate_tree(int id, double* pp, double* m2l0); void ol_evaluate_loop2(int id, double* pp, double* m2l0, double* acc); void ol_evaluate_associated(int id, double* pp, int ass, double* m2l0); void ol_evaluate_sc (int id, double* pp, int emitter, double* polvect, double* m2sc); void ol_evaluate_sc2(int id, double* pp, int emitter, double* polvect, double* m2sc); void ol_evaluate_cc (int id, double* pp, double* tree, double* m2cc, double *m2ewcc); void ol_evaluate_cc2(int id, double* pp, double* tree, double* m2cc, double *m2ewcc); void ol_evaluate_ccmatrix (int id, double* pp, double* tree, double* m2cc, double* m2ewcc); void ol_evaluate_ccmatrix2(int id, double* pp, double* tree, double* m2cc, double* m2ewcc); } // private static member definitions std::string OpenLoops_Interface::s_olprefix = std::string(""); bool OpenLoops_Interface::s_ignore_model = false; bool OpenLoops_Interface::s_exit_on_error = true; bool OpenLoops_Interface::s_ass_func = false; int OpenLoops_Interface::s_ass_ew = 0; std::map OpenLoops_Interface::s_evgen_params; // private static member definitions std::map OpenLoops_Interface::s_procmap; size_t OpenLoops_Interface::s_vmode; OpenLoops_Interface::OpenLoops_Interface() : ME_Generator_Base("OpenLoops") { RegisterDefaults(); }; OpenLoops_Interface::~OpenLoops_Interface() { ol_finish(); } void OpenLoops_Interface::RegisterDefaults() const { Settings& s = Settings::GetMainSettings(); s["OL_VERBOSITY"].SetDefault("0"); s["OL_VMODE"].SetDefault(0); s["OL_EXIT_ON_ERROR"].SetDefault(true); s["OL_IGNORE_MODEL"].SetDefault(false); // find OL installation prefix with several overwrite options char *var=NULL; s_olprefix = rpa->gen.Variable("SHERPA_CPP_PATH")+"/Process/OpenLoops"; s_olprefix = string(((var=getenv("OL_PREFIX"))==NULL ? s_olprefix : var)); struct stat st; if(stat(s_olprefix.c_str(), &st) != 0) s_olprefix = OPENLOOPS_PREFIX; s["OL_PREFIX"].SetDefault(s_olprefix); s_olprefix = s["OL_PREFIX"].Get(); } int OpenLoops_Interface::TranslatedEWRenormalisationScheme() const { switch (ToType(rpa->gen.Variable("EW_REN_SCHEME"))) { case MODEL::ew_scheme::alpha0: return 0; break; case MODEL::ew_scheme::Gmu: return 1; break; case MODEL::ew_scheme::alphamZ: return 2; break; case MODEL::ew_scheme::GmumZsW: return 21; break; case MODEL::ew_scheme::alphamZsW: return 22; break; default: THROW(fatal_error,"Chosen EW_SCHEME/EW_REN_SCHEME unknown to OpenLoops."); } return -1; } bool OpenLoops_Interface::Initialize(MODEL::Model_Base* const model, BEAM::Beam_Spectra_Handler* const beam, PDF::ISR_Handler *const isr) { msg_Info()<<"Initialising OpenLoops generator from "<(); s_exit_on_error = s["OL_EXIT_ON_ERROR"].Get(); if (s_ignore_model) { msg_Info()<(); msg_Tracking()<GetLibraryFunction("SherpaOpenLoops", "ol_evaluate_associated")); if (assfunc) s_ass_func=true; ol_set_init_error_fatal(0); // set OL verbosity std::string ol_verbosity = s["OL_VERBOSITY"].Get(); SetParameter("verbose",ol_verbosity); // tell OL about the current model and check whether accepted std::string modelname(model->Name()); if (modelname=="SMEHC") modelname="HEFT"; if (!s_ignore_model) SetParameter("model", modelname); // Propagate model parameters to OpenLoops if(dynamic_cast(model)) SetParametersUFO(model); else SetParametersSM(model); // set nf in alpha-s evolution int asnf0(isr->PDF(0)?isr->PDF(0)->ASInfo().m_nf:-1); if (asnf0==-1) asnf0=MODEL::as->Nf(1.e20); int asnf1(isr->PDF(1)?isr->PDF(1)->ASInfo().m_nf:-1); if (asnf1==-1) asnf1=MODEL::as->Nf(1.e20); if (asnf0==asnf1) SetParameter("minnf_alphasrun", asnf0); // set OL path SetParameter("install_path", s_olprefix.c_str()); #ifdef USING__MPI if (mpi->Size()>1) SetParameter("splash","0"); #endif // set remaining OL parameters specified by user for (const auto& key : s["OL_PARAMETERS"].GetKeys()) { const auto val = s["OL_PARAMETERS"][key].SetDefault("").Get(); if (key == "add_associated_ew") s_ass_ew = ToType(val); s_evgen_params[key] = val; SetParameter(key, val); } for (const auto& key : s["OL_INTEGRATION_PARAMETERS"].GetKeys()) { const auto val = s["OL_INTEGRATION_PARAMETERS"][key] .SetDefault("") .Get(); SetParameter(key, val); } if (s_vmode==2) SetParameter("ir_on",2); char welcomestr[700]; ol_welcome(welcomestr); msg_Info()<gen.AddCitation(1,cite.str()); return true; } // Propagate model parameters to OpenLoops in the standard model void OpenLoops_Interface::SetParametersSM(const MODEL::Model_Base* model) { // set ew scheme to as(mZ), irrespective of the Sherpa scheme, // we give parameters to OL as as(MZ) and masses SetParameter("ew_scheme",2); // ew-renorm-scheme to Gmu by default SetParameter("ew_renorm_scheme",TranslatedEWRenormalisationScheme()); // set particle masses/widths int tmparr[] = {kf_e, kf_mu, kf_tau, kf_u, kf_d, kf_s, kf_c, kf_b, kf_t, kf_Wplus, kf_Z, kf_h0}; vector pdgids (tmparr, tmparr + sizeof(tmparr) / sizeof(tmparr[0]) ); for (size_t i=0; i0.0) SetParameter("mass("+ToString(id)+")", flav.Mass()); if (flav.Width()>0.0) SetParameter("width("+ToString(id)+")", flav.Width()); if (flav.IsFermion() && flav.Yuk()>0.0 && flav.Mass()!=flav.Yuk()) { SetParameter("yuk("+ToString(id)+")", flav.Yuk()); if (flav.IsQuark()) { // not supported/needed for leptons if (model->ScalarNumber(std::string("YukawaScheme"))==1) SetParameter("muy("+ToString(id)+")", Flavour(kf_h0).Mass(true)); else SetParameter("muy("+ToString(id)+")", flav.Yuk()); } } } // Set CKM parameters if (model->ComplexConstant("CKM_0_2")!=Complex(0.0,0.0) || model->ComplexConstant("CKM_2_0")!=Complex(0.0,0.0)) { SetParameter("ckmorder", 3); } else if (model->ComplexConstant("CKM_1_2")!=Complex(0.0,0.0) || model->ComplexConstant("CKM_2_1")!=Complex(0.0,0.0)) { SetParameter("ckmorder", 2); } else if (model->ComplexConstant("CKM_0_1")!=Complex(0.0,0.0) || model->ComplexConstant("CKM_1_0")!=Complex(0.0,0.0)) { SetParameter("ckmorder", 1); } else { SetParameter("ckmorder", 0); } } void OpenLoops_Interface::SetParametersUFO(const MODEL::Model_Base* model) { // All external UFO parameters are stored in this map for(MODEL::ScalarConstantsMap::const_iterator it=model->ScalarConstants().begin(); it!=model->ScalarConstants().end(); ++it) SetParameter(it->first, it->second); } void OpenLoops_Interface::SwitchMode(const int mode) { for (const auto& kv : s_evgen_params) SetParameter(kv.first, kv.second); } int OpenLoops_Interface::RegisterProcess(const ATOOLS::Flavour_Vector& isflavs, const ATOOLS::Flavour_Vector& fsflavs, int amptype) { PHASIC::Subprocess_Info ii; PHASIC::Subprocess_Info fi; for (auto fl : isflavs) ii.m_ps.push_back(PHASIC::Subprocess_Info(fl)); for (auto fl : fsflavs) fi.m_ps.push_back(PHASIC::Subprocess_Info(fl)); return RegisterProcess(ii,fi,amptype); } int OpenLoops_Interface::RegisterProcess(const Subprocess_Info& is, const Subprocess_Info& fs, int amptype) { DEBUG_FUNC(""); string shprocname(PHASIC::Process_Base::GenerateName(is,fs)),olprocname(""); Flavour_Vector isflavs(is.GetExternal()); for (size_t i=0; i::const_iterator it=s_procmap.begin(); it!=s_procmap.end();++it) msg_Tracking()<first<<": "<second< pp(5*momenta.size()); for (size_t i=0; i pp(5*momenta.size()); for (size_t i=0; i m2l1(3); ol_evaluate_loop(id, &pp[0], &res, &m2l1[0], &acc); virt.Finite()=m2l1[0]; virt.IR()=m2l1[1]; virt.IR2()=m2l1[2]; msg_Debugging()<<"Born = "< pp(5*momenta.size()); for (size_t i=0; i cc_qcd(dim*(dim-1)/2, 0.0); double cc_ew, dummy_tree; if(type == Tree) ol_evaluate_cc(id, &pp[0], &dummy_tree, &cc_qcd[0], &cc_ew); else if(type == Loop2) ol_evaluate_cc2(id, &pp[0], &dummy_tree, &cc_qcd[0], &cc_ew); else THROW(fatal_error, "Unknown amplitude type"); if(emitter>spectator) std::swap(emitter, spectator); size_t index = emitter+spectator*(spectator-1)/2; return cc_qcd[index]; } void OpenLoops_Interface::PopulateColorCorrelatorMatrix(int id, const Vec4D_Vector& momenta, double& born2, double* ccmatrix, AmplitudeType type) { /* In principle no need to return the born2 (the squared uncorrelated ME) because it is proportional to the diagonal elements of the ccmatrix. Expose it nonetheless for validation purposes. */ vector pp(5*momenta.size()); for (size_t i=0; i pp(5*momenta.size()); for (size_t i=0; i "< void HandleParameterStatus(int err, const std::string & key, ValueType value) { if (err==0) { msg_Debugging()<<"Setting OpenLoops parameter: "<:: operator()(const ME_Generator_Key &key) const { return new OpenLoops::OpenLoops_Interface(); } void ATOOLS::Getter:: PrintInfo(ostream &str,const size_t width) const { str<<"Interface to the OpenLoops loop ME generator"; }