diff --git a/FixedOrderGen/t/CMakeLists.txt b/FixedOrderGen/t/CMakeLists.txt index eb00af1..b16fb1a 100644 --- a/FixedOrderGen/t/CMakeLists.txt +++ b/FixedOrderGen/t/CMakeLists.txt @@ -1,108 +1,108 @@ set(tst_dir "${CMAKE_CURRENT_SOURCE_DIR}") foreach(tst W_reconstruct_enu W_2j_classify W_nj_classify) add_executable(test_${tst} ${tst_dir}/${tst}.cc) target_link_libraries(test_${tst} hejfog_lib) add_test(NAME ${tst} COMMAND test_${tst} WORKING_DIRECTORY ${tst_dir}) endforeach() # this only tests if the runcard actually works, not if the result is correct add_test( NAME main_2j COMMAND HEJFOG ${tst_dir}/config_2j.yml ) add_test( NAME main_h2j COMMAND HEJFOG ${tst_dir}/config_h2j.yml ) add_test( NAME main_h2j_decay COMMAND HEJFOG ${tst_dir}/config_h2j_decay.yml ) add_test( NAME peakpt COMMAND HEJFOG ${tst_dir}/config_2j_peak.yml ) # check that uno emission doesn't change FKL xs add_executable(FKL_uno FKL_uno.cc) target_link_libraries(FKL_uno hejfog_lib) add_test( NAME FKL_uno # calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20 COMMAND FKL_uno ${tst_dir}/config_h3j_uno.yml 0.0243548 0.000119862 ) # xs tests add_executable(xs_gen xs_gen.cc) target_link_libraries(xs_gen hejfog_lib) ## Higgs add_test( NAME xs_h2j # calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20 COMMAND xs_gen ${tst_dir}/config_h2j.yml 2.04928 0.00956022 ) add_test( NAME xs_h3j # calculated with HEJ revision bd4388fe55cbc3f5a7b6139096456c551294aa31 COMMAND xs_gen ${tst_dir}/config_h3j.yml 1.07807 0.0132409 ) add_test( NAME xs_h5j # calculated with HEJ revision dbde2ffbb3b383ae6709b2424d8f0f9d5658270b COMMAND xs_gen ${tst_dir}/config_h5j.yml 0.0112504 0.000199633 ) add_test( NAME xs_h3j_uno # calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20 COMMAND xs_gen ${tst_dir}/config_h3j_uno.yml 0.00347538 3.85875e-05 ) add_test( NAME xs_h2j_decay # calculated with HEJ revision 9570e3809613272ac4b8bf3236279ba23cf64d20 COMMAND xs_gen ${tst_dir}/config_h2j_decay.yml 0.00466994 2.20995e-05 ) ## pure jets add_test( NAME xs_2j # calculated with "combined" HEJ svn r3480 COMMAND xs_gen ${tst_dir}/config_2j.yml 86.42031848e06 590570 ) add_test( NAME xs_3j_uno # calculated with HEJ revision b40e0212b144cdd267df19333b574cc7b91847f1 COMMAND xs_gen ${tst_dir}/config_3j_uno.yml 520697 8948.18 ) add_test( NAME xs_3j_qqx # calculated with HEJ revision b40e0212b144cdd267df19333b574cc7b91847f1 COMMAND xs_gen ${tst_dir}/config_3j_qqx.yml 122233 1613.04 ) add_test( NAME xs_4j_qqx # calculated with HEJ revision b40e0212b144cdd267df19333b574cc7b91847f1 COMMAND xs_gen ${tst_dir}/config_4j_qqx.yml 29805.4 581.473 ) add_test( NAME xs_4j # calculated with HEJ revision 13207b5f67a5f40a2141aa7ee515b022bd4efb65 COMMAND xs_gen ${tst_dir}/config_4j.yml 915072 15402.4 ) ## W add_test( NAME xs_W2j # calculated with HEJ revision 987bb30a7985a24a7961f98cfbbc74d3a7992970 COMMAND xs_gen ${tst_dir}/config_Wm2j.yml 231.404 3.43798 ) add_test( NAME xs_W3j_uno # calculated with HEJ revision 987bb30a7985a24a7961f98cfbbc74d3a7992970 COMMAND xs_gen ${tst_dir}/config_Wp3j_uno.yml 0.139372 0.00248345 ) add_test( NAME xs_W3j_eqqx # calculated with HEJ revision 987bb30a7985a24a7961f98cfbbc74d3a7992970 COMMAND xs_gen ${tst_dir}/config_Wp3j_qqx.yml 8.45323 0.103449 ) add_test( - NAME xs_W5j_qqx + NAME xs_W4j_qqx # calculated with HEJ revision 987bb30a7985a24a7961f98cfbbc74d3a7992970 COMMAND xs_gen ${tst_dir}/config_Wp4j_qqx.yml 0.0851908 0.00300447 ) diff --git a/FixedOrderGen/t/FKL_uno.cc b/FixedOrderGen/t/FKL_uno.cc index 1e766f6..cefa8d6 100644 --- a/FixedOrderGen/t/FKL_uno.cc +++ b/FixedOrderGen/t/FKL_uno.cc @@ -1,90 +1,90 @@ /** * check that adding uno emissions doesn't change the FKL cross section * * \authors The HEJ collaboration (see AUTHORS for details) * \date 2019-2020 * \copyright GPLv2 or later */ #include #include #include #include #include #include "HEJ/Event.hh" #include "HEJ/event_types.hh" #include "HEJ/PDG_codes.hh" #include "HEJ/Ranlux64.hh" #include "HEJ/ScaleFunction.hh" #include "config.hh" #include "EventGenerator.hh" #include "Subleading.hh" #include "Status.hh" //! throw error if condition not fulfilled #define ASSERT(x) if(!(x)) { \ - throw std::logic_error("ASSERTion '" #x "' failed."); \ + throw std::logic_error("Assertion '" #x "' failed."); \ } namespace { constexpr double invGeV2_to_pb = 389379292.; } int main(int argn, char const *argv[]){ using namespace HEJFOG; if(argn != 4){ std::cerr << "Usage: " << argv[0] << " config.yml xs xs_err"; return EXIT_FAILURE; } const double xs_ref = std::stod(argv[2]); const double err_ref = std::stod(argv[3]); (void) err_ref; auto config = load_config(argv[1]); config.subleading_fraction = 0.37; std::shared_ptr ran{std::make_shared()}; HEJFOG::EventGenerator generator{ config.process, config.beam, HEJ::ScaleGenerator{ config.scales.base, config.scales.factors, config.scales.max_ratio }, config.jets, config.pdf_id, config.subleading_fraction, config.subleading_channels, config.particle_decays, config.Higgs_coupling, config.ew_parameters, ran }; double xs = 0., xs_err = 0.; std::size_t uno_found = 0; for (std::size_t trials = 0; trials < config.events; ++trials){ auto ev = generator.gen_event(); if(generator.status() != good) continue; ASSERT(ev); if(ev->type() != HEJ::event_type::FKL){ ++uno_found; continue; } xs += ev->central().weight; xs_err += ev->central().weight*ev->central().weight; } xs *= invGeV2_to_pb/config.events; xs_err = std::sqrt(xs_err); xs_err *= invGeV2_to_pb/config.events; std::cout << xs_ref << " ~ " << xs << " +- " << xs_err << '\n'; std::cout << uno_found << " events with unordered emission" << std::endl; ASSERT(uno_found > 0); ASSERT(std::abs(xs - xs_ref) < 3*xs_err); ASSERT(xs_err < 0.05*xs); return EXIT_SUCCESS; } diff --git a/FixedOrderGen/t/W_2j_classify.cc b/FixedOrderGen/t/W_2j_classify.cc index a9a8ddd..76bdf47 100644 --- a/FixedOrderGen/t/W_2j_classify.cc +++ b/FixedOrderGen/t/W_2j_classify.cc @@ -1,168 +1,165 @@ /** * \brief check that the PSP generates only "valid" W + 2 jets events * * \authors The HEJ collaboration (see AUTHORS for details) * \date 2019-2020 * \copyright GPLv2 or later */ -#ifdef NDEBUG -#undef NDEBUG -#endif #include #include #include #include #include "fastjet/JetDefinition.hh" #include "HEJ/EWConstants.hh" #include "HEJ/exceptions.hh" #include "HEJ/Mixmax.hh" #include "HEJ/Particle.hh" #include "HEJ/PDF.hh" #include "HEJ/PDG_codes.hh" #include "Decay.hh" #include "JetParameters.hh" #include "PhaseSpacePoint.hh" #include "Process.hh" #include "Status.hh" #include "Subleading.hh" namespace { using namespace HEJFOG; using namespace HEJ; void print_psp(PhaseSpacePoint const & psp){ std::cerr << "Process:\n" << psp.incoming()[0].type << " + "<< psp.incoming()[1].type << " -> "; for(auto const & out: psp.outgoing()){ std::cerr << out.type << " "; } std::cerr << "\n"; } void bail_out(PhaseSpacePoint const & psp, std::string msg){ print_psp(psp); throw std::logic_error{msg}; } bool is_up_type(Particle const & part){ return HEJ::is_anyquark(part) && !(std::abs(part.type)%2); } bool is_down_type(Particle const & part){ return HEJ::is_anyquark(part) && std::abs(part.type)%2; } bool check_W2j(PhaseSpacePoint const & psp, ParticleID const W_type){ bool found_quark = false; bool found_anti = false; std::vector out_partons; std::vector Wp; for(auto const & p: psp.outgoing()){ if(p.type == W_type) Wp.push_back(p); else if(is_parton(p)) out_partons.push_back(p); else bail_out(psp, "Found particle with is not " +std::to_string(int(W_type))+" or parton"); } if(Wp.size() != 1 || out_partons.size() != 2){ bail_out(psp, "Found wrong number of outgoing partons"); } for(std::size_t j=0; j<2; ++j){ auto const & in = psp.incoming()[j]; auto const & out = out_partons[j]; if(is_quark(in) || is_antiquark(in)) { found_quark = true; if(in.type != out.type) { // switch in quark type -> Wp couples to it if(found_anti){ // already found qq for coupling to W bail_out(psp, "Found second up/down pair"); } else if(std::abs(in.type)>4 || std::abs(out.type)>4){ bail_out(psp, "Found bottom/top pair"); } found_anti = true; if( is_up_type(in)) { // "up" in if(W_type > 0){ // -> only allowed u -> Wp + d if(in.type < 0 || is_up_type(out) || out.type < 0) bail_out(psp, "u -/> Wp + d"); } else { // -> only allowed ux -> Wm + dx if(in.type > 0 || is_up_type(out) || out.type > 0) bail_out(psp, "ux -/> Wm + dx"); } } else { // "down" in if(W_type > 0){ // -> only allowed dx -> Wp + ux if(in.type > 0 || is_down_type(out) || out.type > 0) bail_out(psp, "dx -/> Wp + ux"); } else { // -> only allowed d -> Wm + u if(in.type < 0 || is_down_type(out) || out.type < 0) bail_out(psp, "d -/> Wm + u"); } } } } } if(!found_quark) { bail_out(psp, "Found no initial quarks"); } else if(!found_anti){ bail_out(psp, "Found no up/down pair"); } return true; } } int main(){ constexpr std::size_t n_psp_base = 1337; const JetParameters jet_para{ fastjet::JetDefinition(fastjet::JetAlgorithm::antikt_algorithm, 0.4), 30, 5, 30}; PDF pdf(11000, pid::proton, pid::proton); constexpr double E_cms = 13000.; constexpr double subl_change = 0.5; const Subleading subl_channels(~0l); const ParticlesDecayMap boson_decays{ {pid::Wp, {Decay{ {pid::e_bar, pid::nu_e}, 1.} }}, {pid::Wm, {Decay{ {pid::e, pid::nu_e_bar}, 1.} }} }; const EWConstants ew_constants{246.2196508, ParticleProperties{80.385, 2.085}, ParticleProperties{91.187, 2.495}, ParticleProperties{125, 0.004165} }; HEJ::Mixmax ran{}; // Wp2j Process proc {{pid::proton,pid::proton}, 2, pid::Wp, {}}; std::size_t n_psp = n_psp_base; for( std::size_t i = 0; i try again ++n_psp; } } std::cout << "Wp+2j: Took " << n_psp << " to generate " << n_psp_base << " successfully PSP (" << 1.*n_psp/n_psp_base << " trials/PSP)" << std::endl; // Wm2j proc = Process{{pid::proton,pid::proton}, 2, pid::Wm, {}}; n_psp = n_psp_base; for( std::size_t i = 0; i try again ++n_psp; } } std::cout << "Wm+2j: Took " << n_psp << " to generate " << n_psp_base << " successfully PSP (" << 1.*n_psp/n_psp_base << " trials/PSP)" << std::endl; std::cout << "All processes passed." << std::endl; return EXIT_SUCCESS; } diff --git a/FixedOrderGen/t/W_nj_classify.cc b/FixedOrderGen/t/W_nj_classify.cc index 2a9cc91..aa12ae4 100644 --- a/FixedOrderGen/t/W_nj_classify.cc +++ b/FixedOrderGen/t/W_nj_classify.cc @@ -1,208 +1,205 @@ /** * \brief check that the PSP generates the all W+jet subleading processes * * \authors The HEJ collaboration (see AUTHORS for details) * \date 2019-2020 * \copyright GPLv2 or later */ -#ifdef NDEBUG -#undef NDEBUG -#endif #include #include #include #include #include #include #include #include #include "HEJ/Event.hh" #include "HEJ/event_types.hh" #include "HEJ/EWConstants.hh" #include "HEJ/exceptions.hh" #include "HEJ/Mixmax.hh" #include "HEJ/PDF.hh" #include "HEJ/PDG_codes.hh" #include "fastjet/JetDefinition.hh" #include "Decay.hh" #include "JetParameters.hh" #include "PhaseSpacePoint.hh" #include "Process.hh" #include "Status.hh" #include "Subleading.hh" namespace { using namespace HEJFOG; using namespace HEJ; void print_psp(PhaseSpacePoint const & psp){ std::cerr << "Process:\n" << psp.incoming()[0].type << " + "<< psp.incoming()[1].type << " -> "; for(auto const & out: psp.outgoing()){ std::cerr << out.type << " "; } std::cerr << "\n"; } void bail_out(PhaseSpacePoint const & psp, std::string msg){ print_psp(psp); throw std::logic_error{msg}; } } int main(){ constexpr std::size_t n_psp_base = 10375; const JetParameters jet_para{ fastjet::JetDefinition(fastjet::JetAlgorithm::antikt_algorithm, 0.4), 30, 5, 30}; PDF pdf(11000, pid::proton, pid::proton); constexpr double E_cms = 13000.; constexpr double subl_change = 0.8; const ParticlesDecayMap boson_decays{ {pid::Wp, {Decay{ {pid::e_bar, pid::nu_e}, 1.} }}, {pid::Wm, {Decay{ {pid::e, pid::nu_e_bar}, 1.} }} }; const EWConstants ew_constants{246.2196508, ParticleProperties{80.385, 2.085}, ParticleProperties{91.187, 2.495}, ParticleProperties{125, 0.004165} }; HEJ::Mixmax ran{}; Subleading subl_channels(~0l); std::vector allowed_types{event_type::FKL, event_type::unob, event_type::unof, event_type::qqxexb, event_type::qqxexf}; std::cout << "Wp3j" << std::endl; // Wp3j Process proc {{pid::proton,pid::proton}, 3, pid::Wp, {}}; std::size_t n_psp = n_psp_base; #if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ < 6) // gcc version < 6 explicitly needs hash function for enum // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 std::unordered_map> type_counter; #else std::unordered_map type_counter; #endif for( std::size_t i = 0; i try again ++n_psp; } } std::cout << "Wp+3j: Took " << n_psp << " to generate " << n_psp_base << " successfully PSP (" << 1.*n_psp/n_psp_base << " trials/PSP)" << std::endl; std::cout << "States by classification:\n"; for(auto const & entry: type_counter){ const double fraction = static_cast(entry.second)/n_psp_base; const int percent = std::round(100*fraction); std::cout << std::left << std::setw(25) << (name(entry.first) + std::string(":")) << entry.second << " (" << percent << "%)\n"; } for(auto const & t: allowed_types){ if(type_counter[t] < 0.05 * n_psp_base){ std::cerr << "Less than 5% of the events are of type " << name(t) << std::endl; return EXIT_FAILURE; } } // Wm3j - only uno proc = Process{{pid::proton,pid::proton}, 3, pid::Wm, {}}; n_psp = n_psp_base; subl_channels.reset(); subl_channels.set(subleading::uno); allowed_types = {event_type::FKL, event_type::unob, event_type::unof}; type_counter.clear(); for( std::size_t i = 0; i try again ++n_psp; } } std::cout << "Wm+3j (only uno): Took " << n_psp << " to generate " << n_psp_base << " successfully PSP (" << 1.*n_psp/n_psp_base << " trials/PSP)" << std::endl; std::cout << "States by classification:\n"; for(auto const & entry: type_counter){ const double fraction = static_cast(entry.second)/n_psp_base; const int percent = std::round(100*fraction); std::cout << std::left << std::setw(25) << (name(entry.first) + std::string(":")) << entry.second << " (" << percent << "%)\n"; } for(auto const & t: allowed_types){ if(type_counter[t] < 0.05 * n_psp_base){ std::cerr << "Less than 5% of the events are of type " << name(t) << std::endl; return EXIT_FAILURE; } } // Wm4j proc = Process{{pid::proton,pid::proton}, 4, pid::Wm, {}}; n_psp = n_psp_base; subl_channels.set(); allowed_types = {event_type::FKL, event_type::unob, event_type::unof, event_type::qqxexb, event_type::qqxexf, event_type::qqxmid}; type_counter.clear(); for( std::size_t i = 0; i try again ++n_psp; } } std::cout << "Wm+4j: Took " << n_psp << " to generate " << n_psp_base << " successfully PSP (" << 1.*n_psp/n_psp_base << " trials/PSP)" << std::endl; std::cout << "States by classification:\n"; for(auto const & entry: type_counter){ const double fraction = static_cast(entry.second)/n_psp_base; const int percent = std::round(100*fraction); std::cout << std::left << std::setw(25) << (name(entry.first) + std::string(":")) << entry.second << " (" << percent << "%)\n"; } for(auto const & t: allowed_types){ if(type_counter[t] < 0.03 * n_psp_base){ std::cerr << "Less than 3% of the events are of type " << name(t) << std::endl; return EXIT_FAILURE; } } std::cout << "All processes passed." << std::endl; return EXIT_SUCCESS; } diff --git a/FixedOrderGen/t/W_reconstruct_enu.cc b/FixedOrderGen/t/W_reconstruct_enu.cc index ee8f55c..ad9eadc 100644 --- a/FixedOrderGen/t/W_reconstruct_enu.cc +++ b/FixedOrderGen/t/W_reconstruct_enu.cc @@ -1,79 +1,79 @@ /** * \brief that the reconstruction of the W works * * \authors The HEJ collaboration (see AUTHORS for details) * \date 2019-2020 * \copyright GPLv2 or later */ -#ifdef NDEBUG -#undef NDEBUG -#endif - -#include #include #include #include #include #include "HEJ/Event.hh" #include "HEJ/Mixmax.hh" #include "HEJ/ScaleFunction.hh" #include "config.hh" #include "EventGenerator.hh" #include "Status.hh" +//! throw error if condition not fulfilled +#define ASSERT(x) if(!(x)) { \ + throw std::logic_error("Assertion '" #x "' failed."); \ + } + namespace { using namespace HEJFOG; using namespace HEJ; constexpr std::size_t num_events = 1000; constexpr double invGeV2_to_pb = 389379292.; } double get_xs(std::string config_name){ auto config { load_config(config_name) }; config.events = num_events; std::shared_ptr ran{std::make_shared(11)}; HEJFOG::EventGenerator generator{ config.process, config.beam, HEJ::ScaleGenerator{ config.scales.base, config.scales.factors, config.scales.max_ratio }, config.jets, config.pdf_id, config.subleading_fraction, config.subleading_channels, config.particle_decays, config.Higgs_coupling, config.ew_parameters, ran }; double xs = 0.; for (std::size_t trials = 0; trials < config.events; ++trials){ auto ev = generator.gen_event(); if(generator.status() != good) continue; - assert(ev); + ASSERT(ev); ev->central().weight *= invGeV2_to_pb; ev->central().weight /= config.events; xs += ev->central().weight; } return xs; } int main(){ double xs_W{ get_xs("config_Wp_2j.yml")}; double xs_enu{ get_xs("config_Wp_2j_decay.yml")}; if(std::abs(xs_W/xs_enu-1.)>1e-6){ std::cerr << "Reconstructing the W in the runcard gave a different results (" << xs_W << " vs. "<< xs_enu << " -> " << std::abs(xs_W/xs_enu-1.)*100 << "%)\n"; return EXIT_FAILURE; } return EXIT_SUCCESS; }