diff --git a/CMakeLists.txt b/CMakeLists.txt index ccb01c3..063b160 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,396 +1,396 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) set(CMAKE_LEGACY_CYGWIN_WIN32 0) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project("HEJ" VERSION 2.0.5 LANGUAGES C CXX) # Set a default build type if none was specified set(default_build_type "RelWithDebInfo") if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to '${default_build_type}' as none was specified.") set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() ## Flags for the compiler. No warning allowed. if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") elseif (MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX /EHsc") endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 14) ## Create Version set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") # Get the latest abbreviated commit hash of the working branch execute_process( COMMAND git rev-parse HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE PROJECT_GIT_REVISION OUTPUT_STRIP_TRAILING_WHITESPACE ) # Get the current working branch execute_process( COMMAND git rev-parse --abbrev-ref HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE PROJECT_GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE ) ## target directories for install set(INSTALL_INCLUDE_DIR_BASE include) set(INSTALL_INCLUDE_DIR ${INSTALL_INCLUDE_DIR_BASE}/HEJ) set(INSTALL_BIN_DIR bin) set(INSTALL_LIB_DIR lib) set(INSTALL_CONFIG_DIR lib/cmake/HEJ) ## Template files configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Templates/Version.hh.in ${PROJECT_BINARY_DIR}/include/HEJ/Version.hh @ONLY ) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Templates/HEJ-config.cc.in ${PROJECT_BINARY_DIR}/src/bin/HEJ-config.cc @ONLY ) # Generate CMake config file include(CMakePackageConfigHelpers) configure_package_config_file( cmake/Templates/hej-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CONFIG_DIR}/hej-config.cmake INSTALL_DESTINATION ${INSTALL_CONFIG_DIR} PATH_VARS INSTALL_INCLUDE_DIR_BASE INSTALL_LIB_DIR ) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CONFIG_DIR}/hej-config-version.cmake COMPATIBILITY SameMajorVersion ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CONFIG_DIR}/hej-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_CONFIG_DIR}/hej-config-version.cmake DESTINATION ${INSTALL_CONFIG_DIR}) ## Add directories and find dependences include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) find_package(fastjet REQUIRED) include_directories(${fastjet_INCLUDE_DIRS}) find_package(CLHEP 2.3 REQUIRED) include_directories(${CLHEP_INCLUDE_DIRS}) find_package(LHAPDF REQUIRED) include_directories(${LHAPDF_INCLUDE_DIRS}) ## Amend unintuitive behaviour of FindBoost.cmake ## Priority of BOOST_ROOT over BOOSTROOT matches FindBoost.cmake ## at least for cmake 3.12 if(DEFINED BOOST_ROOT) message("BOOST_ROOT set - only looking for Boost in ${BOOST_ROOT}") set(Boost_NO_BOOST_CMAKE ON) elseif(DEFINED BOOSTROOT) message("BOOSTROOT set - only looking for Boost in ${BOOSTROOT}") set(Boost_NO_BOOST_CMAKE ON) endif() find_package(Boost REQUIRED COMPONENTS iostreams) include_directories(${Boost_INCLUDE_DIRS}) find_package(yaml-cpp) # requiring yaml does not work with fedora include_directories(${YAML_CPP_INCLUDE_DIR}) if(${EXCLUDE_HepMC}) message(STATUS "Skipping HepMC") # avoid "unused variable" warning if EXCLUDE_rivet is set by user set(EXCLUDE_rivet TRUE) else() find_package(HepMC 2) endif() if(${HepMC_FOUND}) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHEJ_BUILD_WITH_HepMC_VERSION=${HepMC_VERSION_MAJOR}" ) include_directories(${HepMC_INCLUDE_DIRS}) if(${EXCLUDE_rivet}) message(STATUS "Skipping rivet") else() find_package(rivet) endif() if(${rivet_FOUND}) include_directories(${rivet_INCLUDE_DIRS}) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHEJ_BUILD_WITH_RIVET" ) endif() endif() if(${EXCLUDE_QCDloop}) message(STATUS "Skipping QCDloop") else() find_package(QCDloop 2) endif() if(${QCDloop_FOUND}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHEJ_BUILD_WITH_QCDLOOP") include_directories(SYSTEM ${QCDloop_INCLUDE_DIRS}) endif() if(${EXCLUDE_HighFive}) message(STATUS "Skipping HighFive") else() find_package(HighFive QUIET) find_package_handle_standard_args( HighFive CONFIG_MODE ) endif() if(${HighFive_FOUND}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHEJ_BUILD_WITH_HDF5") include_directories($<TARGET_PROPERTY:HighFive,INTERFACE_INCLUDE_DIRECTORIES>) endif() add_subdirectory(src) ## define executable add_executable(HEJ src/bin/HEJ.cc) ## link libraries target_link_libraries(HEJ hejlib) add_executable(HEJ-config src/bin/HEJ-config.cc) file(GLOB hej_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/HEJ/*.hh ${PROJECT_BINARY_DIR}/include/HEJ/*.hh ) file(GLOB hej_detail_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/HEJ/detail/*.hh) file(GLOB lhef_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/LHEF/*.h) install(FILES ${hej_headers} DESTINATION ${INSTALL_INCLUDE_DIR}) install(FILES ${hej_detail_headers} DESTINATION ${INSTALL_INCLUDE_DIR}/detail/) install(FILES ${lhef_headers} DESTINATION ${INSTALL_INCLUDE_DIR_BASE}/LHEF/) install(TARGETS HEJ HEJ-config DESTINATION ${INSTALL_BIN_DIR}) ## tests enable_testing() set(tst_dir "${CMAKE_CURRENT_SOURCE_DIR}/t") set(tst_ME_data_dir "${tst_dir}/ME_data") # test event classification -add_executable(test_classify_new ${tst_dir}/test_classify_new.cc) -target_link_libraries(test_classify_new hejlib) -add_test( - NAME t_classify_new - COMMAND test_classify_new - ) add_executable(test_classify ${tst_dir}/test_classify.cc) target_link_libraries(test_classify hejlib) add_test( NAME t_classify - COMMAND test_classify ${tst_dir}/classify_ref ${tst_dir}/classify.lhe.gz + COMMAND test_classify + ) +add_executable(test_classify_ref ${tst_dir}/test_classify_ref.cc) +target_link_libraries(test_classify_ref hejlib) +add_test( + NAME t_classify_ref + COMMAND test_classify_ref ${tst_dir}/classify_ref ${tst_dir}/classify.lhe.gz ) add_test( - NAME t_classify_4j - COMMAND test_classify ${tst_dir}/classify_ref_4j ${tst_dir}/4j.lhe.gz + NAME t_classify_ref_4j + COMMAND test_classify_ref ${tst_dir}/classify_ref_4j ${tst_dir}/4j.lhe.gz ) # test phase space point add_executable(test_psp ${tst_dir}/test_psp.cc) target_link_libraries(test_psp hejlib) add_test( NAME t_psp COMMAND test_psp ${tst_dir}/psp_gen.lhe.gz ) # test importing scales add_library(scales SHARED ${tst_dir}/scales.cc) add_executable(test_scale_import ${tst_dir}/test_scale_import) target_link_libraries(test_scale_import hejlib) add_test( NAME t_scale_import COMMAND test_scale_import ${tst_dir}/jet_config_with_import.yml ) # test scale arithmetic (e.g. 2*H_T/4) add_executable(test_scale_arithmetics ${tst_dir}/test_scale_arithmetics) target_link_libraries(test_scale_arithmetics hejlib) add_test( NAME t_scale_arithmetics COMMAND test_scale_arithmetics ${tst_dir}/jet_config.yml ${tst_dir}/2j.lhe.gz ) # test "ParameterDescription" add_executable(test_descriptions ${tst_dir}/test_descriptions) target_link_libraries(test_descriptions hejlib) add_test( NAME t_descriptions COMMAND test_descriptions ) # test "EventParameters*Weight" add_executable(test_parameters ${tst_dir}/test_parameters) target_link_libraries(test_parameters hejlib) add_test( NAME test_parameters COMMAND test_parameters ) # test colour generation add_executable(test_colours ${tst_dir}/test_colours) target_link_libraries(test_colours hejlib) add_test( NAME t_colour_flow COMMAND test_colours ) # test matrix elements add_executable(test_ME_generic ${tst_dir}/test_ME_generic.cc) target_link_libraries(test_ME_generic hejlib) add_test( NAME t_ME_j COMMAND test_ME_generic ${tst_ME_data_dir}/config_mtinf.yml ${tst_ME_data_dir}/ME_jets.dat ${tst_ME_data_dir}/PSP_jets.lhe.gz ) add_test( NAME t_ME_h COMMAND test_ME_generic ${tst_ME_data_dir}/config_mtinf.yml ${tst_ME_data_dir}/ME_h_mtinf.dat ${tst_ME_data_dir}/PSP_h.lhe.gz ) if(${QCDloop_FOUND}) add_test( NAME t_ME_h_mt COMMAND test_ME_generic ${tst_ME_data_dir}/config_mt.yml ${tst_ME_data_dir}/ME_h_mt_tree.dat ${tst_ME_data_dir}/PSP_h.lhe.gz ) add_test( NAME t_ME_h_mtmb COMMAND test_ME_generic ${tst_ME_data_dir}/config_mtmb.yml ${tst_ME_data_dir}/ME_h_mtmb_tree.dat ${tst_ME_data_dir}/PSP_h.lhe.gz ) endif() add_test( NAME t_ME_w_FKL COMMAND test_ME_generic ${tst_ME_data_dir}/config_w_ME.yml ${tst_ME_data_dir}/ME_w_FKL_tree.dat ${tst_ME_data_dir}/PSP_w_FKL.lhe.gz ) add_test( NAME t_ME_w_FKL_virt COMMAND test_ME_generic ${tst_ME_data_dir}/config_w_ME.yml ${tst_ME_data_dir}/ME_w_FKL_virt.dat ${tst_ME_data_dir}/PSP_w_FKL.lhe.gz ) add_test( NAME t_ME_Wp COMMAND test_ME_generic ${tst_ME_data_dir}/config_w_ME.yml ${tst_ME_data_dir}/ME_Wp.dat ${tst_ME_data_dir}/PSP_Wp.lhe.gz ) add_test( NAME t_ME_Wm COMMAND test_ME_generic ${tst_ME_data_dir}/config_w_ME.yml ${tst_ME_data_dir}/ME_Wm.dat ${tst_ME_data_dir}/PSP_Wm.lhe.gz ) # test main executable if(${HepMC_FOUND}) file(READ "${tst_dir}/jet_config.yml" config) file(WRITE "${tst_dir}/jet_config_withHepMC.yml" "${config} - tst.hepmc") if(${rivet_FOUND}) file(READ "${tst_dir}/jet_config_withHepMC.yml" config) file(WRITE "${tst_dir}/jet_config_withRivet.yml" "${config}\n\nanalysis:\n rivet: MC_XS\n output: tst") add_test( NAME t_main COMMAND HEJ ${tst_dir}/jet_config_withRivet.yml ${tst_dir}/2j.lhe.gz ) else() # no rivet add_test( NAME t_main COMMAND HEJ ${tst_dir}/jet_config_withHepMC.yml ${tst_dir}/2j.lhe.gz ) endif() if(${HepMC_VERSION_MAJOR} GREATER 2) add_executable(check_hepmc ${tst_dir}/check_hepmc.cc) target_link_libraries(check_hepmc hejlib) # check that HepMC output is correct add_test( NAME t_hepmc COMMAND check_hepmc tst.hepmc ) endif() else() # no HepMC add_test( NAME t_main COMMAND HEJ ${tst_dir}/jet_config.yml ${tst_dir}/2j.lhe.gz ) endif() # check that LHEF output is correct add_executable(check_lhe ${tst_dir}/check_lhe.cc) target_link_libraries(check_lhe hejlib) add_test( NAME t_lhe COMMAND check_lhe tst.lhe ) # check HDF5 reader if(${HighFive_FOUND}) add_executable(test_hdf5 ${tst_dir}/test_hdf5.cc) target_link_libraries(test_hdf5 hejlib) add_test( NAME t_hdf5 COMMAND test_hdf5 ${tst_dir}/Wm9-g4-repack.hdf5 ) endif() # test boson reconstruction add_executable(cmp_events ${tst_dir}/cmp_events.cc) target_link_libraries(cmp_events hejlib) add_test( NAME t_epnu_2j_noW COMMAND cmp_events ${tst_dir}/epnu2jLOFKL_unweight.lhe.tar.gz ${tst_dir}/epnu2jLOFKL_unweight_noW.lhe.gz ) # test resummed result add_executable(check_res ${tst_dir}/check_res.cc) target_link_libraries(check_res hejlib) if(${TEST_ALL}) # deactivate long tests by default add_test( NAME t_2j COMMAND check_res ${tst_dir}/2j.lhe.gz 3.49391e+07 419684 ) add_test( NAME t_3j COMMAND check_res ${tst_dir}/3j.lhe.gz 2.37902e+06 25746.6 ) add_test( NAME t_4j COMMAND check_res ${tst_dir}/4j.lhe.gz 603713 72822.6 ) add_test( NAME t_h_3j COMMAND check_res ${tst_dir}/h_3j.lhe.gz 0.821622 0.0220334 ) add_test( NAME t_h_3j_unof COMMAND check_res ${tst_dir}/h_3j_uno.lhe.gz 0.0127362 0.000271555 unof ) add_test( NAME t_h_3j_unob COMMAND check_res ${tst_dir}/h_3j_uno.lhe.gz 0.0130615 0.000224793 unob ) add_test( NAME t_epnu_2j COMMAND check_res ${tst_dir}/epnu2jLOFKL_unweight.lhe.tar.gz 262.7 3 ) add_test( NAME t_MGepnu_3j COMMAND check_res ${tst_dir}/MGepnu3j_unweighted.tar.gz 38.9512 1 ) add_test( NAME t_MGemnubar_3j COMMAND check_res ${tst_dir}/MGemnubar3j_unweighted.tar.gz 24.1575 1 ) add_test( NAME t_MGepnu_3j_splitf COMMAND check_res ${tst_dir}/MGepnu3j_unweighted.tar.gz 2.91995 0.0463182 splitf ) add_test( NAME t_MGepnu_3j_splitb COMMAND check_res ${tst_dir}/MGepnu3j_unweighted.tar.gz 3.40708 0.0550975 splitb ) add_test( NAME t_MGepnu_4j COMMAND check_res ${tst_dir}/MGepnu4j_unweighted.tar.gz 10.2542 0.135106 ) add_test( NAME t_MGemnubar_4j COMMAND check_res ${tst_dir}/MGemnubar4j_unweighted.tar.gz 5.57909 0.0300496 ) add_test( NAME t_MGepnu_4j_qqxmid COMMAND check_res ${tst_dir}/MGepnu4j_unweighted.tar.gz 0.732084 0.005 qqxmid ) endif() diff --git a/t/test_classify.cc b/t/test_classify.cc index e9b0067..bc5ce0f 100644 --- a/t/test_classify.cc +++ b/t/test_classify.cc @@ -1,75 +1,629 @@ /** * \authors The HEJ collaboration (see AUTHORS for details) - * \date 2019 + * \date 2019 * \copyright GPLv2 or later */ -#include <fstream> +#include <iostream> #include <random> -#include <algorithm> -#include "LHEF/LHEF.h" - -#include "HEJ/YAMLreader.hh" -#include "HEJ/event_types.hh" #include "HEJ/Event.hh" -#include "HEJ/EventReader.hh" +#include "HEJ/exceptions.hh" + +#define ASSERT(x) if(!(x)) { \ + throw std::logic_error("Assertion '" #x "' failed."); \ + } -namespace{ - // this is deliberately chosen bigger than in the generation, - // to cluster multiple partons in one jet - constexpr double min_jet_pt = 40.; - const fastjet::JetDefinition jet_def{fastjet::kt_algorithm, 0.4}; +namespace { + const fastjet::JetDefinition jet_def{fastjet::JetAlgorithm::antikt_algorithm, 0.4}; + const double min_jet_pt{30.}; + const std::array<std::string, 6> all_quarks{"-4","-1","1","2","3","4"}; + const std::array<std::string, 7> all_partons{"g","-2","-1","1","2","3","4"}; + const std::array<std::string, 3> all_bosons{"h", "Wp", "Wm"}; + + static std::mt19937_64 ran{0}; void shuffle_particles(HEJ::Event::EventData & ev) { - static std::mt19937_64 ran{0}; std::shuffle(begin(ev.incoming), end(ev.incoming), ran); std::shuffle(begin(ev.outgoing), end(ev.outgoing), ran); } -} -int main(int argn, char** argv) { - if(argn != 3 && argn != 4){ - std::cerr << "Usage: " << argv[0] - << " reference_classification input_file.lhe\n"; - return EXIT_FAILURE; + // if pos_boson = -1 (or not implemented) -> no boson + HEJ::Event::EventData get_process(int const njet, int const pos_boson){ + HEJ::Event::EventData ev; + if(njet == 2){ + switch(pos_boson){ + case 0: + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 198, 33, -170, 291}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-154, 68, 44, 174}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -44, -101, 88, 141}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -322, 322}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 284, 284}, {}}; + return ev; + case 1: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -6, 82, -159, 179}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 195, -106, 74, 265}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-189, 24, 108, 219}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -320, 320}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 343, 343}, {}}; + return ev; + case 2: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -80, -80, -140, 180}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -60, -32, 0, 68}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 140, 112, 177, 281}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -246, 246}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 283, 283}, {}}; + return ev; + default: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -72, 24, 18, 78}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 72, -24, 74, 106}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -46, 46}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 138, 138}, {}}; + return ev; + } + } + if(njet == 3){ + switch(pos_boson){ + case 0: + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 152, -117, -88, 245}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-146, 62, -11, 159}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 126, -72, 96, 174}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-132, 127, 144, 233}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -335, 335}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 476, 476}, {}}; + return ev; + case 1: + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-191, 188, -128, 297}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 72, -76, 257}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 184, -172, -8, 252}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-192, -88, 54, 218}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -591, 591}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 433, 433}, {}}; + return ev; + case 2: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -42, 18, -49, 67}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, -54, -28, 62}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 99, 32, -16, 163}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -45, 4, 72, 85}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -199, 199}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 178, 178}, {}}; + return ev; + case 3: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -65, -32, -76, 105}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -22, 31, -34, 51}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, -67, -36, 77}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 99, 68, -4, 173}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -278, 278}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 128, 128}, {}}; + return ev; + default: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -90, -135, 30, 165}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-108, 198, 76, 238}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, -63, 126, 243}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -207, 207}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 439, 439}, {}}; + return ev; + } + } + if(njet == 4){ + switch(pos_boson){ + case 0: + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 72, -76, 257}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, -155, -64, 261}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 194, 57, 283}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 1, 32, 8, 33}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -143, 186, 307}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -515, 515}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 626, 626}, {}}; + return ev; + case 1: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 61, -162, 263}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 72, -76, 257}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, 135, 144, 281}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -186, 171, 321}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 1, -82, 122, 147}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -535, 535}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 734, 734}, {}}; + return ev; + case 2: + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-180, -27, -164, 245}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-108, 78, -36, 138}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 196, -189, 68, 307}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-107, 136, 76, 189}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 199, 2, 178, 267}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -512, 512}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 634, 634}, {}}; + return ev; + case 3: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, -30, -84, 90}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -72, 22, -96, 122}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 68, 0, -51, 85}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 64, 72, -81, 177}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -48, -64, 84, 116}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -409, 409}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 181, 181}, {}}; + return ev; + case 4: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -72, -49, -72, 113}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -48, 0, -36, 60}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, 54, -36, 66}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 68, -77, -56, 117}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 64, 72, -81, 177}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -407, 407}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 126, 126}, {}}; + return ev; + default: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 248, -56, -122, 282}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 249, 30, -10, 251}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-249, -18, 26, 251}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-248, 44, 199, 321}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -506, 506}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 599, 599}, {}}; + return ev; + } + } + if(njet == 6){ + switch(pos_boson){ + case 0: + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 349, 330, -94, 505}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-315, -300, 0, 435}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 347, 306, 18, 463}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-249, -342, 162, 453}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 345, 312, 284, 545}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-324, -126, 292, 454}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-153, -180, 304, 385}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -1137, 1137}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 2103, 2103}, {}}; + return ev; + case 1: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 242, 241, -182, 387}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 243, 238, -190, 409}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-218, -215, -74, 315}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-224, -224, 112, 336}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 241, 182, 154, 339}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -53, -234, 126, 271}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-231, 12, 156, 279}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -1117, 1117}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 1219, 1219}, {}}; + return ev; + case 2: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 151, 102, -42, 187}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -86, -46, -17, 99}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 152, 153, 0, 249}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -60, -135, 64, 161}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 150, 123, 110, 223}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-154, -49, 98, 189}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-153, -148, 144, 257}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -504, 504}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 861, 861}, {}}; + return ev; + case 3: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 197, -66, 287}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -189, -54, 279}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, -64, 2, 210}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 158, 6, 283}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-199, -184, 172, 321}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 196, 168, 177, 313}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 4, -86, 92, 126}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -745, 745}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 1074, 1074}, {}}; + return ev; + case 4: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 151, 102, -42, 187}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -86, -133, -14, 159}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-154, -104, -8, 186}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -60, 11, 0, 61}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 152, 153, 0, 249}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 150, 125, 90, 215}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-153, -154, 126, 251}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -578, 578}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 730, 730}, {}}; + return ev; + case 5: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -15, -90, -94, 131}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -11, 82, -74, 111}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 23, -80, -64, 105}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -48, -25, -36, 65}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, 99, -16, 101}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 68, 92, -18, 170}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { -5, -78, 54, 95}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -513, 513}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 265, 265}, {}}; + return ev; + case 6: + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 197, -66, 287}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 4, -84, -18, 86}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -60, -36, 210}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 196, -78, -36, 214}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, 45, 0, 205}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-199, -178, 2, 267}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 158, 6, 283}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -850, 850}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 702, 702}, {}}; + return ev; + default: + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-350, -112, -280, 462}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 347, 266, -322, 543}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-349, -314, -38, 471}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 349, 348, 12, 493}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, {-342, -54, 23, 347}, {}}); + ev.outgoing.push_back({HEJ::ParticleID::gluon, { 345, -134, 138, 395}, {}}); + ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -1589, 1589}, {}}; + ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 1122, 1122}, {}}; + return ev; + } + } + throw HEJ::unknown_option{"unkown process"}; + } + + bool couple_quark(std::string const & boson, std::string & quark){ + if(abs(HEJ::to_ParticleID(boson)) == HEJ::ParticleID::Wp){ + auto qflav{ HEJ::to_ParticleID(quark) }; + if(!HEJ::is_anyquark(qflav)) return false; + const int W_charge = HEJ::to_ParticleID(boson)>0?1:-1; + if(W_charge*qflav < 0 && !(abs(qflav)%2)) return false; // not anti-down + if(W_charge*qflav > 0 && (abs(qflav)%2)) return false; // not up + quark=std::to_string(qflav-W_charge); + } + return true; + } + + // create event corresponding from given Configuration + HEJ::Event parse_configuration( + std::array<std::string,2> const & in, std::vector<std::string> const & out + ){ + auto boson = std::find_if(out.cbegin(), out.cend(), + [](std::string id){ return !HEJ::is_parton(HEJ::to_ParticleID(id)); }); + int const pos_boson = (boson == out.cend())?-1:std::distance(out.cbegin(), boson); + + size_t njets = out.size(); + if(boson != out.cend()) --njets; + + HEJ::Event::EventData ev{get_process(njets, pos_boson)}; + ASSERT((pos_boson==-1) || (ev.outgoing[pos_boson].type == HEJ::ParticleID::higgs)); + for(size_t i=0; i<out.size(); ++i){ + ev.outgoing[i].type = HEJ::to_ParticleID(out[i]); + } + for(size_t i=0; i<in.size(); ++i){ + ev.incoming[i].type = HEJ::to_ParticleID(in[i]); + } + shuffle_particles(ev); + + return ev.cluster(jet_def, min_jet_pt); + } + + bool match_expectation( HEJ::event_type::EventType expected, + std::array<std::string,2> const & in, std::vector<std::string> const & out + ){ + HEJ::Event ev{parse_configuration(in,out)}; + if(ev.type() != expected){ + std::cerr << "Expected type " << HEJ::event_type::name(expected) + << " but found " << HEJ::event_type::name(ev.type()) << "\n" << ev; + return false; + } + return true; } - bool OUTPUT_MODE = false; - if(argn == 4 && std::string("OUTPUT")==std::string(argv[3])) - OUTPUT_MODE = true; - - std::fstream ref_file; - if ( OUTPUT_MODE ) { - std::cout << "_______________________USING OUTPUT MODE!_______________________" << std::endl; - ref_file.open(argv[1], std::fstream::out); - } else { - ref_file.open(argv[1], std::fstream::in); + + bool check_fkl(){ + using namespace HEJ; + for(int njet=2; njet<=6; ++njet){ // all multiplicities + if(njet==5) continue; + for(std::string const & first: all_partons) // all quark flavours + for(std::string const & last: all_partons){ + std::array<std::string,2> base_in{first,last}; + std::vector<std::string> base_out(njet, "g"); + base_out.front() = first; + base_out.back() = last; + if(!match_expectation(event_type::FKL, base_in, base_out)) + return false; + for(auto const & boson: all_bosons) // any boson + for(int pos=0; pos<=njet; ++pos){ // at any position + auto in{base_in}; + auto out{base_out}; + // change quark flavours for W + int couple_idx{ std::uniform_int_distribution<int>{0,1}(ran) }; + if(!couple_quark(boson, couple_idx?out.back():out.front())) + continue; + out.insert(out.begin()+pos, boson); + if(!match_expectation(event_type::FKL, in, out)) + return false; + } + } + } + return true; + } + + bool check_uno(){ + using namespace HEJ; + for(int njet=3; njet<=6; ++njet){ // all multiplicities >2 + if(njet==5) continue; + for(std::string const & uno: all_quarks) // all quark flavours + for(std::string const & fkl: all_partons){ + for(int i=0; i<2; ++i){ // forward & backwards + std::array<std::string,2> base_in; + std::vector<std::string> base_out(njet, "g"); + const int uno_pos = i?1:(njet-2); + const int fkl_pos = i?(njet-1):0; + base_in[i?0:1] = uno; + base_in[i?1:0] = fkl; + base_out[uno_pos] = uno; + base_out[fkl_pos] = fkl; + HEJ::event_type::EventType expectation{ i?event_type::unob:event_type::unof }; + if( !match_expectation(expectation, base_in, base_out) ) + return false; + for(auto const & boson: all_bosons){ // any boson + // at any position (higgs only inside FKL chain) + int start = 0; + int end = njet; + if(to_ParticleID(boson) == pid::higgs){ + start = i?(uno_pos+1):fkl_pos; + end = i?(fkl_pos+1):uno_pos; + } + for(int pos=start; pos<=end; ++pos){ + auto in{base_in}; + auto out{base_out}; + // change quark flavours for W + bool couple_idx{ std::uniform_int_distribution<int>{0,1}(ran) }; + if(!couple_quark(boson, couple_idx?out[fkl_pos]:out[uno_pos])) + continue; + out.insert(out.begin()+pos, boson); + if(!match_expectation(expectation, in, out)) + return false; + } + } + } + } + } + return true; } - auto reader{ HEJ::make_reader(argv[2]) }; - - while(reader->read_event()){ - HEJ::Event::EventData data{ reader->hepeup() }; - shuffle_particles(data); - const HEJ::Event ev{ - data.cluster( - jet_def, min_jet_pt - ) - }; - if ( OUTPUT_MODE ) { - ref_file << ev.type() << std::endl; - } else { - std::string line; - if(!std::getline(ref_file,line)) break; - const auto expected{static_cast<HEJ::event_type::EventType>(std::stoi(line))}; - - if(ev.type() != expected){ - using HEJ::event_type::name; - std::cerr << "wrong classification of event:\n" << ev - << "classified as " << name(ev.type()) - << ", is " << name(expected) << '\n'; - return EXIT_FAILURE; + bool check_extremal_qqx(){ + using namespace HEJ; + for(int njet=3; njet<=6; ++njet){ // all multiplicities >2 + if(njet==5) continue; + for(std::string const & qqx: all_quarks) // all quark flavours + for(std::string const & fkl: all_partons){ + for(int i=0; i<2; ++i){ // forward & backwards + std::array<std::string,2> base_in; + std::vector<std::string> base_out(njet, "g"); + const int qqx_pos = i?0:(njet-2); + const int fkl_pos = i?(njet-1):0; + base_in[i?0:1] = "g"; + base_in[i?1:0] = fkl; + base_out[fkl_pos] = fkl; + base_out[qqx_pos] = qqx; + base_out[qqx_pos+1] = std::to_string(HEJ::to_ParticleID(qqx)*-1); + HEJ::event_type::EventType expectation{ i?event_type::qqxexb:event_type::qqxexf }; + if( !match_expectation(expectation, base_in, base_out) ) + return false; + for(auto const & boson: all_bosons){ // any boson + // at any position (higgs only inside FKL chain) + int start = 0; + int end = njet; + if(to_ParticleID(boson) == pid::higgs){ + start = i?(qqx_pos+2):fkl_pos; + end = i?(fkl_pos+1):qqx_pos; + } + for(int pos=start; pos<=end; ++pos){ + auto in{base_in}; + auto out{base_out}; + // change quark flavours for W + bool couple_idx{ std::uniform_int_distribution<int>{0,1}(ran) }; + if(couple_idx || !couple_quark(boson, out[fkl_pos]) ){ + // (randomly) try couple to FKL, else fall-back to qqx + if(!couple_quark(boson, out[qqx_pos])) + couple_quark(boson, out[qqx_pos+1]); + } + out.insert(out.begin()+pos, boson); + if(!match_expectation(expectation, in, out)) + return false; + } + } + } } } + return true; } + bool check_central_qqx(){ + using namespace HEJ; + for(int njet=4; njet<=6; ++njet){ // all multiplicities >3 + if(njet==5) continue; + for(std::string const & qqx: all_quarks) // all quark flavours + for(std::string const & fkl1: all_partons) + for(std::string const & fkl2: all_partons){ + for(int qqx_pos=1; qqx_pos<njet-2; ++qqx_pos){ // any qqx position + std::array<std::string,2> base_in; + std::vector<std::string> base_out(njet, "g"); + base_in[0] = fkl1; + base_in[1] = fkl2; + base_out.front() = fkl1; + base_out.back() = fkl2; + base_out[qqx_pos] = qqx; + base_out[qqx_pos+1] = std::to_string(HEJ::to_ParticleID(qqx)*-1); + if( !match_expectation(event_type::qqxmid, base_in, base_out) ) + return false; + for(auto const & boson: all_bosons) // any boson + for(int pos=0; pos<=njet; ++pos){ // at any position + if( to_ParticleID(boson) == pid::higgs + && (pos==qqx_pos || pos==qqx_pos+1) ) + continue; + auto in{base_in}; + auto out{base_out}; + // change quark flavours for W + int couple_idx{ std::uniform_int_distribution<int>{0,2}(ran) }; + // (randomly) try couple to FKL, else fall-back to qqx + if( couple_idx == 0 && couple_quark(boson, out.front()) ){} + else if( couple_idx == 1 && couple_quark(boson, out.back()) ){} + else { + if(!couple_quark(boson, out[qqx_pos])) + couple_quark(boson, out[qqx_pos+1]); + } + out.insert(out.begin()+pos, boson); + if(!match_expectation(event_type::qqxmid, in, out)) + return false; + } + } + } + } + return true; + } + + // this checks a (non excessive) list of Non-HEJ states + bool check_non_HEJ(){ + auto type{ HEJ::event_type::FixedOrder}; + return + // 2j - crossing lines + match_expectation(type, {"g","2"}, {"2","g"}) + && match_expectation(type, {"-1","g"}, {"g","-1"}) + && match_expectation(type, {"1","-1"}, {"-1","1"}) + && match_expectation(type, {"g","2"}, {"2","g","h"}) + && match_expectation(type, {"1","2"}, {"2","h","1"}) + && match_expectation(type, {"1","-1"}, {"h","-1","1"}) + && match_expectation(type, {"g","2"}, {"Wp","1","g"}) + && match_expectation(type, {"1","-1"}, {"-2","Wp","1"}) + && match_expectation(type, {"4","g"}, {"g","3","Wp"}) + && match_expectation(type, {"1","-2"}, {"-1","Wm","1"}) + && match_expectation(type, {"g","3"}, {"4","g","Wm"}) + && match_expectation(type, {"1","3"}, {"Wm","4","1"}) + // 2j - qqx + && match_expectation(type, {"g","g"}, {"1","-1"}) + && match_expectation(type, {"g","g"}, {"-2","2","h"}) + && match_expectation(type, {"g","g"}, {"-4","Wp","3"}) + && match_expectation(type, {"g","g"}, {"Wm","-1","2"}) + // 3j - crossing lines + && match_expectation(type, {"g","4"}, {"4","g","g"}) + && match_expectation(type, {"-1","g"}, {"g","g","-1"}) + && match_expectation(type, {"1","3"}, {"3","g","1"}) + && match_expectation(type, {"-2","2"}, {"2","g","-2","h"}) + && match_expectation(type, {"-3","g"}, {"g","g","Wp","-4"}) + && match_expectation(type, {"1","-2"}, {"Wm","-1","g","1"}) + && match_expectation(type, {"-1","g"}, {"1","-1","-1"}) + // higgs inside uno + && match_expectation(type, {"-1","g"}, {"g","h","-1","g"}) + && match_expectation(type, {"-1","1"}, {"g","h","-1","1"}) + && match_expectation(type, {"g","2"}, {"g","2","h","g"}) + && match_expectation(type, {"-1","1"}, {"-1","1","h","g"}) + // higgs outside uno + && match_expectation(type, {"-1","g"}, {"h","g","-1","g"}) + && match_expectation(type, {"-1","1"}, {"-1","1","g","h"}) + // higgs inside qqx + && match_expectation(type, {"g","g"}, {"-1","h","1","g","g"}) + && match_expectation(type, {"g","g"}, {"g","-1","h","1","g"}) + && match_expectation(type, {"g","g"}, {"g","g","2","h","-2"}) + // higgs outside qqx + && match_expectation(type, {"g","g"}, {"h","-1","1","g","g"}) + && match_expectation(type, {"g","g"}, {"g","g","2","-2","h"}) + // 4j - two uno + && match_expectation(type, {"-2","2"}, {"g","-2","2","g"}) + && match_expectation(type, {"1","3"}, {"g","1","h","3","g"}) + && match_expectation(type, {"1","2"}, {"g","1","3","Wp","g"}) + && match_expectation(type, {"1","-2"}, {"g","Wm","1","-1","g"}) + // 4j - two gluon outside + && match_expectation(type, {"g","4"}, {"g","4","g","g"}) + && match_expectation(type, {"1","3"}, {"1","3","h","g","g"}) + && match_expectation(type, {"1","2"}, {"1","3","g","Wp","g"}) + && match_expectation(type, {"1","-2"}, {"1","Wm","-1","g","g"}) + && match_expectation(type, {"-1","g"}, {"g","g","-1","g"}) + && match_expectation(type, {"1","3"}, {"g","g","1","3","h"}) + && match_expectation(type, {"1","2"}, {"g","g","1","Wp","3"}) + && match_expectation(type, {"1","-2"}, {"Wm","g","g","1","-1"}) + // 4j - ggx+uno + && match_expectation(type, {"g","4"}, {"1","-1","4","g"}) + && match_expectation(type, {"2","g"}, {"g","2","-3","3"}) + && match_expectation(type, {"g","4"}, {"1","-1","h","4","g"}) + && match_expectation(type, {"2","g"}, {"g","2","-3","3","h"}) + && match_expectation(type, {"g","4"}, {"Wp","1","-1","3","g"}) + && match_expectation(type, {"2","g"}, {"g","2","-4","Wp","3"}) + && match_expectation(type, {"g","4"}, {"2","Wm","-1","4","g"}) + && match_expectation(type, {"2","g"}, {"g","2","Wp","-3","4"}) + // 3j - crossing+uno + && match_expectation(type, {"1","4"}, {"g","4","1"}) + && match_expectation(type, {"1","4"}, {"4","1","g"}) + && match_expectation(type, {"1","4"}, {"g","h","4","1"}) + && match_expectation(type, {"-1","-3"},{"Wm","g","-4","-1"}) + && match_expectation(type, {"1","4"}, {"3","1","Wp","g"}) + && match_expectation(type, {"1","4"}, {"3","1","g","h"}) + // 3j - crossing+qqx + && match_expectation(type, {"1","g"}, {"-1","1","g","1"}) + && match_expectation(type, {"1","g"}, {"-1","1","1","g"}) + && match_expectation(type, {"g","1"}, {"1","g","1","-1"}) + && match_expectation(type, {"g","1"}, {"g","1","1","-1"}) + && match_expectation(type, {"1","g"}, {"2","-2","g","1"}) + && match_expectation(type, {"1","g"}, {"2","-2","1","g"}) + && match_expectation(type, {"g","1"}, {"1","g","-2","2"}) + && match_expectation(type, {"g","1"}, {"g","1","-2","2"}) + && match_expectation(type, {"1","g"}, {"-1","1","h","g","1"}) + && match_expectation(type, {"1","g"}, {"-1","h","1","1","g"}) + && match_expectation(type, {"g","1"}, {"1","g","1","h","-1"}) + && match_expectation(type, {"g","1"}, {"h","g","1","1","-1"}) + && match_expectation(type, {"1","g"}, {"2","-2","1","g","h"}) + && match_expectation(type, {"g","1"}, {"g","h","1","-2","2"}) + && match_expectation(type, {"1","g"}, {"Wp","3","-4","g","1"}) + && match_expectation(type, {"3","g"}, {"-2","Wm","1","3","g"}) + && match_expectation(type, {"g","1"}, {"1","g","Wm","-3","4"}) + && match_expectation(type, {"g","-3"}, {"g","-3","-1","Wp","2"}) + // 4j- gluon in qqx + && match_expectation(type, {"g","1"}, {"1","g","-1","1"}) + && match_expectation(type, {"1","g"}, {"1","-1","g","1"}) + && match_expectation(type, {"g","1"}, {"1","g","Wm","-2","1"}) + && match_expectation(type, {"2","g"}, {"2","-2","g","Wp","1"}) + && match_expectation(type, {"g","g"}, {"Wp","3","g","-4","g"}) + && match_expectation(type, {"1","g"}, {"1","h","-1","g","1"}) + // 6j - two qqx + && match_expectation(type, {"g","g"}, {"1","-1","g","g","1","-1"}) + && match_expectation(type, {"g","g"}, {"1","-1","g","1","-1","g"}) + && match_expectation(type, {"g","g"}, {"g","1","-1","g","1","-1"}) + && match_expectation(type, {"g","g"}, {"g","1","-1","1","-1","g"}) + && match_expectation(type, {"g","g"}, {"g","1","1","-1","-1","g"}) + && match_expectation(type, {"g","g"}, {"h","1","-1","g","g","1","-1"}) + && match_expectation(type, {"g","g"}, {"1","Wp","-2","g","1","-1","g"}) + && match_expectation(type, {"g","g"}, {"g","1","Wp","-1","g","1","-2"}) + && match_expectation(type, {"g","g"}, {"g","1","-1","Wm","2","-1","g"}) + && match_expectation(type, {"g","g"}, {"g","1","2","-1","Wm","-1","g"}) + // random stuff (can be non-physical) + && match_expectation(type, {"g","g"}, {"1","-2","2","-1"}) // != 2 qqx + && match_expectation(type, {"g","g"}, {"1","-2","2","g"}) // could be qqx + && match_expectation(type, {"e+","e-"},{"1","-1"}) // bad initial state + && match_expectation(type, {"1","e-"}, {"g","1","Wm"}) // bad initial state + && match_expectation(type, {"h","g"}, {"g","g"}) // bad initial state + && match_expectation(type, {"-1","g"}, {"-1","1","1"}) // bad qqx + && match_expectation(type, {"-1","g"}, {"1","1","-1"}) // crossing in bad qqx + && match_expectation(type, {"-1","g"}, {"-2","1","1","Wp"}) // bad qqx + && match_expectation(type, {"1","2"}, {"1","-1","g","g","g","2"}) // bad qqx + && match_expectation(type, {"1","2"}, {"1","-1","-2","g","g","2"}) // gluon in bad qqx + && match_expectation(type, {"g","g"}, {"-1","2","g","g"}) // wrong back qqx + && match_expectation(type, {"g","g"}, {"g","g","2","1"}) // wrong forward qqx + && match_expectation(type, {"g","g"}, {"g","-2","1","g"}) // wrong central qqx + ; + } + + // Two boson states, that are currently not implemented + bool check_bad_FS(){ + auto type{ HEJ::event_type::bad_final_state}; + return + match_expectation(type, {"g","g"}, {"g","h","h","g"}) + && match_expectation(type, {"g","g"}, {"h","g","h","g"}) + && match_expectation(type, {"g","-1"}, {"g","h","Wp","-2"}) + && match_expectation(type, {"-3","-1"},{"-4","g","Wp","Wp","-2"}) + && match_expectation(type, {"-4","-1"},{"-3","Wp","g","Wm","-2"}) + && match_expectation(type, {"-4","-1"},{"g","-3","Wp","Wm","-2"}) + ; + } +} + +int main() { + // tests for "no false negatives" + // i.e. all HEJ-configurations get classified correctly + if(!check_fkl()) return EXIT_FAILURE; + if(!check_uno()) return EXIT_FAILURE; + if(!check_extremal_qqx()) return EXIT_FAILURE; + if(!check_central_qqx()) return EXIT_FAILURE; + // test for "no false positive" + // i.e. non-HEJ gives non-HEJ + if(!check_non_HEJ()) return EXIT_FAILURE; + if(!check_bad_FS()) return EXIT_FAILURE; + //! @TODO missing: + //! checks for partons sharing a jet + + return EXIT_SUCCESS; } diff --git a/t/test_classify_new.cc b/t/test_classify_new.cc deleted file mode 100644 index bc5ce0f..0000000 --- a/t/test_classify_new.cc +++ /dev/null @@ -1,629 +0,0 @@ -/** - * \authors The HEJ collaboration (see AUTHORS for details) - * \date 2019 - * \copyright GPLv2 or later - */ -#include <iostream> -#include <random> - -#include "HEJ/Event.hh" -#include "HEJ/exceptions.hh" - -#define ASSERT(x) if(!(x)) { \ - throw std::logic_error("Assertion '" #x "' failed."); \ - } - -namespace { - const fastjet::JetDefinition jet_def{fastjet::JetAlgorithm::antikt_algorithm, 0.4}; - const double min_jet_pt{30.}; - const std::array<std::string, 6> all_quarks{"-4","-1","1","2","3","4"}; - const std::array<std::string, 7> all_partons{"g","-2","-1","1","2","3","4"}; - const std::array<std::string, 3> all_bosons{"h", "Wp", "Wm"}; - - static std::mt19937_64 ran{0}; - - void shuffle_particles(HEJ::Event::EventData & ev) { - std::shuffle(begin(ev.incoming), end(ev.incoming), ran); - std::shuffle(begin(ev.outgoing), end(ev.outgoing), ran); - } - - // if pos_boson = -1 (or not implemented) -> no boson - HEJ::Event::EventData get_process(int const njet, int const pos_boson){ - HEJ::Event::EventData ev; - if(njet == 2){ - switch(pos_boson){ - case 0: - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 198, 33, -170, 291}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-154, 68, 44, 174}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -44, -101, 88, 141}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -322, 322}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 284, 284}, {}}; - return ev; - case 1: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -6, 82, -159, 179}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 195, -106, 74, 265}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-189, 24, 108, 219}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -320, 320}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 343, 343}, {}}; - return ev; - case 2: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -80, -80, -140, 180}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -60, -32, 0, 68}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 140, 112, 177, 281}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -246, 246}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 283, 283}, {}}; - return ev; - default: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -72, 24, 18, 78}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 72, -24, 74, 106}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -46, 46}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 138, 138}, {}}; - return ev; - } - } - if(njet == 3){ - switch(pos_boson){ - case 0: - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 152, -117, -88, 245}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-146, 62, -11, 159}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 126, -72, 96, 174}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-132, 127, 144, 233}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -335, 335}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 476, 476}, {}}; - return ev; - case 1: - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-191, 188, -128, 297}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 72, -76, 257}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 184, -172, -8, 252}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-192, -88, 54, 218}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -591, 591}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 433, 433}, {}}; - return ev; - case 2: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -42, 18, -49, 67}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, -54, -28, 62}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 99, 32, -16, 163}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -45, 4, 72, 85}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -199, 199}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 178, 178}, {}}; - return ev; - case 3: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -65, -32, -76, 105}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -22, 31, -34, 51}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, -67, -36, 77}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 99, 68, -4, 173}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -278, 278}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 128, 128}, {}}; - return ev; - default: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -90, -135, 30, 165}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-108, 198, 76, 238}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, -63, 126, 243}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -207, 207}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 439, 439}, {}}; - return ev; - } - } - if(njet == 4){ - switch(pos_boson){ - case 0: - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 72, -76, 257}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, -155, -64, 261}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 194, 57, 283}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 1, 32, 8, 33}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -143, 186, 307}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -515, 515}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 626, 626}, {}}; - return ev; - case 1: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 61, -162, 263}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 72, -76, 257}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, 135, 144, 281}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -186, 171, 321}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 1, -82, 122, 147}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -535, 535}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 734, 734}, {}}; - return ev; - case 2: - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-180, -27, -164, 245}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-108, 78, -36, 138}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 196, -189, 68, 307}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-107, 136, 76, 189}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 199, 2, 178, 267}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -512, 512}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 634, 634}, {}}; - return ev; - case 3: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, -30, -84, 90}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -72, 22, -96, 122}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 68, 0, -51, 85}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 64, 72, -81, 177}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -48, -64, 84, 116}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -409, 409}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 181, 181}, {}}; - return ev; - case 4: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -72, -49, -72, 113}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -48, 0, -36, 60}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, 54, -36, 66}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 68, -77, -56, 117}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 64, 72, -81, 177}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -407, 407}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 126, 126}, {}}; - return ev; - default: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 248, -56, -122, 282}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 249, 30, -10, 251}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-249, -18, 26, 251}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-248, 44, 199, 321}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -506, 506}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 599, 599}, {}}; - return ev; - } - } - if(njet == 6){ - switch(pos_boson){ - case 0: - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 349, 330, -94, 505}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-315, -300, 0, 435}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 347, 306, 18, 463}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-249, -342, 162, 453}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 345, 312, 284, 545}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-324, -126, 292, 454}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-153, -180, 304, 385}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -1137, 1137}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 2103, 2103}, {}}; - return ev; - case 1: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 242, 241, -182, 387}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 243, 238, -190, 409}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-218, -215, -74, 315}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-224, -224, 112, 336}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 241, 182, 154, 339}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -53, -234, 126, 271}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-231, 12, 156, 279}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -1117, 1117}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 1219, 1219}, {}}; - return ev; - case 2: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 151, 102, -42, 187}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -86, -46, -17, 99}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 152, 153, 0, 249}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -60, -135, 64, 161}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 150, 123, 110, 223}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-154, -49, 98, 189}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-153, -148, 144, 257}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -504, 504}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 861, 861}, {}}; - return ev; - case 3: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 197, -66, 287}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -189, -54, 279}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, -64, 2, 210}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 158, 6, 283}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-199, -184, 172, 321}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 196, 168, 177, 313}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 4, -86, 92, 126}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -745, 745}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 1074, 1074}, {}}; - return ev; - case 4: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 151, 102, -42, 187}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -86, -133, -14, 159}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-154, -104, -8, 186}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -60, 11, 0, 61}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 152, 153, 0, 249}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 150, 125, 90, 215}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-153, -154, 126, 251}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -578, 578}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 730, 730}, {}}; - return ev; - case 5: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -15, -90, -94, 131}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -11, 82, -74, 111}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 23, -80, -64, 105}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -48, -25, -36, 65}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -12, 99, -16, 101}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 68, 92, -18, 170}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { -5, -78, 54, 95}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -513, 513}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 265, 265}, {}}; - return ev; - case 6: - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 198, 197, -66, 287}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 4, -84, -18, 86}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-198, -60, -36, 210}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 196, -78, -36, 214}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-200, 45, 0, 205}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-199, -178, 2, 267}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::higgs, { 199, 158, 6, 283}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -850, 850}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 702, 702}, {}}; - return ev; - default: - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-350, -112, -280, 462}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 347, 266, -322, 543}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-349, -314, -38, 471}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 349, 348, 12, 493}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, {-342, -54, 23, 347}, {}}); - ev.outgoing.push_back({HEJ::ParticleID::gluon, { 345, -134, 138, 395}, {}}); - ev.incoming[0] = {HEJ::ParticleID::gluon, { 0, 0, -1589, 1589}, {}}; - ev.incoming[1] = {HEJ::ParticleID::gluon, { 0, 0, 1122, 1122}, {}}; - return ev; - } - } - throw HEJ::unknown_option{"unkown process"}; - } - - bool couple_quark(std::string const & boson, std::string & quark){ - if(abs(HEJ::to_ParticleID(boson)) == HEJ::ParticleID::Wp){ - auto qflav{ HEJ::to_ParticleID(quark) }; - if(!HEJ::is_anyquark(qflav)) return false; - const int W_charge = HEJ::to_ParticleID(boson)>0?1:-1; - if(W_charge*qflav < 0 && !(abs(qflav)%2)) return false; // not anti-down - if(W_charge*qflav > 0 && (abs(qflav)%2)) return false; // not up - quark=std::to_string(qflav-W_charge); - } - return true; - } - - // create event corresponding from given Configuration - HEJ::Event parse_configuration( - std::array<std::string,2> const & in, std::vector<std::string> const & out - ){ - auto boson = std::find_if(out.cbegin(), out.cend(), - [](std::string id){ return !HEJ::is_parton(HEJ::to_ParticleID(id)); }); - int const pos_boson = (boson == out.cend())?-1:std::distance(out.cbegin(), boson); - - size_t njets = out.size(); - if(boson != out.cend()) --njets; - - HEJ::Event::EventData ev{get_process(njets, pos_boson)}; - ASSERT((pos_boson==-1) || (ev.outgoing[pos_boson].type == HEJ::ParticleID::higgs)); - for(size_t i=0; i<out.size(); ++i){ - ev.outgoing[i].type = HEJ::to_ParticleID(out[i]); - } - for(size_t i=0; i<in.size(); ++i){ - ev.incoming[i].type = HEJ::to_ParticleID(in[i]); - } - shuffle_particles(ev); - - return ev.cluster(jet_def, min_jet_pt); - } - - bool match_expectation( HEJ::event_type::EventType expected, - std::array<std::string,2> const & in, std::vector<std::string> const & out - ){ - HEJ::Event ev{parse_configuration(in,out)}; - if(ev.type() != expected){ - std::cerr << "Expected type " << HEJ::event_type::name(expected) - << " but found " << HEJ::event_type::name(ev.type()) << "\n" << ev; - return false; - } - return true; - } - - bool check_fkl(){ - using namespace HEJ; - for(int njet=2; njet<=6; ++njet){ // all multiplicities - if(njet==5) continue; - for(std::string const & first: all_partons) // all quark flavours - for(std::string const & last: all_partons){ - std::array<std::string,2> base_in{first,last}; - std::vector<std::string> base_out(njet, "g"); - base_out.front() = first; - base_out.back() = last; - if(!match_expectation(event_type::FKL, base_in, base_out)) - return false; - for(auto const & boson: all_bosons) // any boson - for(int pos=0; pos<=njet; ++pos){ // at any position - auto in{base_in}; - auto out{base_out}; - // change quark flavours for W - int couple_idx{ std::uniform_int_distribution<int>{0,1}(ran) }; - if(!couple_quark(boson, couple_idx?out.back():out.front())) - continue; - out.insert(out.begin()+pos, boson); - if(!match_expectation(event_type::FKL, in, out)) - return false; - } - } - } - return true; - } - - bool check_uno(){ - using namespace HEJ; - for(int njet=3; njet<=6; ++njet){ // all multiplicities >2 - if(njet==5) continue; - for(std::string const & uno: all_quarks) // all quark flavours - for(std::string const & fkl: all_partons){ - for(int i=0; i<2; ++i){ // forward & backwards - std::array<std::string,2> base_in; - std::vector<std::string> base_out(njet, "g"); - const int uno_pos = i?1:(njet-2); - const int fkl_pos = i?(njet-1):0; - base_in[i?0:1] = uno; - base_in[i?1:0] = fkl; - base_out[uno_pos] = uno; - base_out[fkl_pos] = fkl; - HEJ::event_type::EventType expectation{ i?event_type::unob:event_type::unof }; - if( !match_expectation(expectation, base_in, base_out) ) - return false; - for(auto const & boson: all_bosons){ // any boson - // at any position (higgs only inside FKL chain) - int start = 0; - int end = njet; - if(to_ParticleID(boson) == pid::higgs){ - start = i?(uno_pos+1):fkl_pos; - end = i?(fkl_pos+1):uno_pos; - } - for(int pos=start; pos<=end; ++pos){ - auto in{base_in}; - auto out{base_out}; - // change quark flavours for W - bool couple_idx{ std::uniform_int_distribution<int>{0,1}(ran) }; - if(!couple_quark(boson, couple_idx?out[fkl_pos]:out[uno_pos])) - continue; - out.insert(out.begin()+pos, boson); - if(!match_expectation(expectation, in, out)) - return false; - } - } - } - } - } - return true; - } - - bool check_extremal_qqx(){ - using namespace HEJ; - for(int njet=3; njet<=6; ++njet){ // all multiplicities >2 - if(njet==5) continue; - for(std::string const & qqx: all_quarks) // all quark flavours - for(std::string const & fkl: all_partons){ - for(int i=0; i<2; ++i){ // forward & backwards - std::array<std::string,2> base_in; - std::vector<std::string> base_out(njet, "g"); - const int qqx_pos = i?0:(njet-2); - const int fkl_pos = i?(njet-1):0; - base_in[i?0:1] = "g"; - base_in[i?1:0] = fkl; - base_out[fkl_pos] = fkl; - base_out[qqx_pos] = qqx; - base_out[qqx_pos+1] = std::to_string(HEJ::to_ParticleID(qqx)*-1); - HEJ::event_type::EventType expectation{ i?event_type::qqxexb:event_type::qqxexf }; - if( !match_expectation(expectation, base_in, base_out) ) - return false; - for(auto const & boson: all_bosons){ // any boson - // at any position (higgs only inside FKL chain) - int start = 0; - int end = njet; - if(to_ParticleID(boson) == pid::higgs){ - start = i?(qqx_pos+2):fkl_pos; - end = i?(fkl_pos+1):qqx_pos; - } - for(int pos=start; pos<=end; ++pos){ - auto in{base_in}; - auto out{base_out}; - // change quark flavours for W - bool couple_idx{ std::uniform_int_distribution<int>{0,1}(ran) }; - if(couple_idx || !couple_quark(boson, out[fkl_pos]) ){ - // (randomly) try couple to FKL, else fall-back to qqx - if(!couple_quark(boson, out[qqx_pos])) - couple_quark(boson, out[qqx_pos+1]); - } - out.insert(out.begin()+pos, boson); - if(!match_expectation(expectation, in, out)) - return false; - } - } - } - } - } - return true; - } - - bool check_central_qqx(){ - using namespace HEJ; - for(int njet=4; njet<=6; ++njet){ // all multiplicities >3 - if(njet==5) continue; - for(std::string const & qqx: all_quarks) // all quark flavours - for(std::string const & fkl1: all_partons) - for(std::string const & fkl2: all_partons){ - for(int qqx_pos=1; qqx_pos<njet-2; ++qqx_pos){ // any qqx position - std::array<std::string,2> base_in; - std::vector<std::string> base_out(njet, "g"); - base_in[0] = fkl1; - base_in[1] = fkl2; - base_out.front() = fkl1; - base_out.back() = fkl2; - base_out[qqx_pos] = qqx; - base_out[qqx_pos+1] = std::to_string(HEJ::to_ParticleID(qqx)*-1); - if( !match_expectation(event_type::qqxmid, base_in, base_out) ) - return false; - for(auto const & boson: all_bosons) // any boson - for(int pos=0; pos<=njet; ++pos){ // at any position - if( to_ParticleID(boson) == pid::higgs - && (pos==qqx_pos || pos==qqx_pos+1) ) - continue; - auto in{base_in}; - auto out{base_out}; - // change quark flavours for W - int couple_idx{ std::uniform_int_distribution<int>{0,2}(ran) }; - // (randomly) try couple to FKL, else fall-back to qqx - if( couple_idx == 0 && couple_quark(boson, out.front()) ){} - else if( couple_idx == 1 && couple_quark(boson, out.back()) ){} - else { - if(!couple_quark(boson, out[qqx_pos])) - couple_quark(boson, out[qqx_pos+1]); - } - out.insert(out.begin()+pos, boson); - if(!match_expectation(event_type::qqxmid, in, out)) - return false; - } - } - } - } - return true; - } - - // this checks a (non excessive) list of Non-HEJ states - bool check_non_HEJ(){ - auto type{ HEJ::event_type::FixedOrder}; - return - // 2j - crossing lines - match_expectation(type, {"g","2"}, {"2","g"}) - && match_expectation(type, {"-1","g"}, {"g","-1"}) - && match_expectation(type, {"1","-1"}, {"-1","1"}) - && match_expectation(type, {"g","2"}, {"2","g","h"}) - && match_expectation(type, {"1","2"}, {"2","h","1"}) - && match_expectation(type, {"1","-1"}, {"h","-1","1"}) - && match_expectation(type, {"g","2"}, {"Wp","1","g"}) - && match_expectation(type, {"1","-1"}, {"-2","Wp","1"}) - && match_expectation(type, {"4","g"}, {"g","3","Wp"}) - && match_expectation(type, {"1","-2"}, {"-1","Wm","1"}) - && match_expectation(type, {"g","3"}, {"4","g","Wm"}) - && match_expectation(type, {"1","3"}, {"Wm","4","1"}) - // 2j - qqx - && match_expectation(type, {"g","g"}, {"1","-1"}) - && match_expectation(type, {"g","g"}, {"-2","2","h"}) - && match_expectation(type, {"g","g"}, {"-4","Wp","3"}) - && match_expectation(type, {"g","g"}, {"Wm","-1","2"}) - // 3j - crossing lines - && match_expectation(type, {"g","4"}, {"4","g","g"}) - && match_expectation(type, {"-1","g"}, {"g","g","-1"}) - && match_expectation(type, {"1","3"}, {"3","g","1"}) - && match_expectation(type, {"-2","2"}, {"2","g","-2","h"}) - && match_expectation(type, {"-3","g"}, {"g","g","Wp","-4"}) - && match_expectation(type, {"1","-2"}, {"Wm","-1","g","1"}) - && match_expectation(type, {"-1","g"}, {"1","-1","-1"}) - // higgs inside uno - && match_expectation(type, {"-1","g"}, {"g","h","-1","g"}) - && match_expectation(type, {"-1","1"}, {"g","h","-1","1"}) - && match_expectation(type, {"g","2"}, {"g","2","h","g"}) - && match_expectation(type, {"-1","1"}, {"-1","1","h","g"}) - // higgs outside uno - && match_expectation(type, {"-1","g"}, {"h","g","-1","g"}) - && match_expectation(type, {"-1","1"}, {"-1","1","g","h"}) - // higgs inside qqx - && match_expectation(type, {"g","g"}, {"-1","h","1","g","g"}) - && match_expectation(type, {"g","g"}, {"g","-1","h","1","g"}) - && match_expectation(type, {"g","g"}, {"g","g","2","h","-2"}) - // higgs outside qqx - && match_expectation(type, {"g","g"}, {"h","-1","1","g","g"}) - && match_expectation(type, {"g","g"}, {"g","g","2","-2","h"}) - // 4j - two uno - && match_expectation(type, {"-2","2"}, {"g","-2","2","g"}) - && match_expectation(type, {"1","3"}, {"g","1","h","3","g"}) - && match_expectation(type, {"1","2"}, {"g","1","3","Wp","g"}) - && match_expectation(type, {"1","-2"}, {"g","Wm","1","-1","g"}) - // 4j - two gluon outside - && match_expectation(type, {"g","4"}, {"g","4","g","g"}) - && match_expectation(type, {"1","3"}, {"1","3","h","g","g"}) - && match_expectation(type, {"1","2"}, {"1","3","g","Wp","g"}) - && match_expectation(type, {"1","-2"}, {"1","Wm","-1","g","g"}) - && match_expectation(type, {"-1","g"}, {"g","g","-1","g"}) - && match_expectation(type, {"1","3"}, {"g","g","1","3","h"}) - && match_expectation(type, {"1","2"}, {"g","g","1","Wp","3"}) - && match_expectation(type, {"1","-2"}, {"Wm","g","g","1","-1"}) - // 4j - ggx+uno - && match_expectation(type, {"g","4"}, {"1","-1","4","g"}) - && match_expectation(type, {"2","g"}, {"g","2","-3","3"}) - && match_expectation(type, {"g","4"}, {"1","-1","h","4","g"}) - && match_expectation(type, {"2","g"}, {"g","2","-3","3","h"}) - && match_expectation(type, {"g","4"}, {"Wp","1","-1","3","g"}) - && match_expectation(type, {"2","g"}, {"g","2","-4","Wp","3"}) - && match_expectation(type, {"g","4"}, {"2","Wm","-1","4","g"}) - && match_expectation(type, {"2","g"}, {"g","2","Wp","-3","4"}) - // 3j - crossing+uno - && match_expectation(type, {"1","4"}, {"g","4","1"}) - && match_expectation(type, {"1","4"}, {"4","1","g"}) - && match_expectation(type, {"1","4"}, {"g","h","4","1"}) - && match_expectation(type, {"-1","-3"},{"Wm","g","-4","-1"}) - && match_expectation(type, {"1","4"}, {"3","1","Wp","g"}) - && match_expectation(type, {"1","4"}, {"3","1","g","h"}) - // 3j - crossing+qqx - && match_expectation(type, {"1","g"}, {"-1","1","g","1"}) - && match_expectation(type, {"1","g"}, {"-1","1","1","g"}) - && match_expectation(type, {"g","1"}, {"1","g","1","-1"}) - && match_expectation(type, {"g","1"}, {"g","1","1","-1"}) - && match_expectation(type, {"1","g"}, {"2","-2","g","1"}) - && match_expectation(type, {"1","g"}, {"2","-2","1","g"}) - && match_expectation(type, {"g","1"}, {"1","g","-2","2"}) - && match_expectation(type, {"g","1"}, {"g","1","-2","2"}) - && match_expectation(type, {"1","g"}, {"-1","1","h","g","1"}) - && match_expectation(type, {"1","g"}, {"-1","h","1","1","g"}) - && match_expectation(type, {"g","1"}, {"1","g","1","h","-1"}) - && match_expectation(type, {"g","1"}, {"h","g","1","1","-1"}) - && match_expectation(type, {"1","g"}, {"2","-2","1","g","h"}) - && match_expectation(type, {"g","1"}, {"g","h","1","-2","2"}) - && match_expectation(type, {"1","g"}, {"Wp","3","-4","g","1"}) - && match_expectation(type, {"3","g"}, {"-2","Wm","1","3","g"}) - && match_expectation(type, {"g","1"}, {"1","g","Wm","-3","4"}) - && match_expectation(type, {"g","-3"}, {"g","-3","-1","Wp","2"}) - // 4j- gluon in qqx - && match_expectation(type, {"g","1"}, {"1","g","-1","1"}) - && match_expectation(type, {"1","g"}, {"1","-1","g","1"}) - && match_expectation(type, {"g","1"}, {"1","g","Wm","-2","1"}) - && match_expectation(type, {"2","g"}, {"2","-2","g","Wp","1"}) - && match_expectation(type, {"g","g"}, {"Wp","3","g","-4","g"}) - && match_expectation(type, {"1","g"}, {"1","h","-1","g","1"}) - // 6j - two qqx - && match_expectation(type, {"g","g"}, {"1","-1","g","g","1","-1"}) - && match_expectation(type, {"g","g"}, {"1","-1","g","1","-1","g"}) - && match_expectation(type, {"g","g"}, {"g","1","-1","g","1","-1"}) - && match_expectation(type, {"g","g"}, {"g","1","-1","1","-1","g"}) - && match_expectation(type, {"g","g"}, {"g","1","1","-1","-1","g"}) - && match_expectation(type, {"g","g"}, {"h","1","-1","g","g","1","-1"}) - && match_expectation(type, {"g","g"}, {"1","Wp","-2","g","1","-1","g"}) - && match_expectation(type, {"g","g"}, {"g","1","Wp","-1","g","1","-2"}) - && match_expectation(type, {"g","g"}, {"g","1","-1","Wm","2","-1","g"}) - && match_expectation(type, {"g","g"}, {"g","1","2","-1","Wm","-1","g"}) - // random stuff (can be non-physical) - && match_expectation(type, {"g","g"}, {"1","-2","2","-1"}) // != 2 qqx - && match_expectation(type, {"g","g"}, {"1","-2","2","g"}) // could be qqx - && match_expectation(type, {"e+","e-"},{"1","-1"}) // bad initial state - && match_expectation(type, {"1","e-"}, {"g","1","Wm"}) // bad initial state - && match_expectation(type, {"h","g"}, {"g","g"}) // bad initial state - && match_expectation(type, {"-1","g"}, {"-1","1","1"}) // bad qqx - && match_expectation(type, {"-1","g"}, {"1","1","-1"}) // crossing in bad qqx - && match_expectation(type, {"-1","g"}, {"-2","1","1","Wp"}) // bad qqx - && match_expectation(type, {"1","2"}, {"1","-1","g","g","g","2"}) // bad qqx - && match_expectation(type, {"1","2"}, {"1","-1","-2","g","g","2"}) // gluon in bad qqx - && match_expectation(type, {"g","g"}, {"-1","2","g","g"}) // wrong back qqx - && match_expectation(type, {"g","g"}, {"g","g","2","1"}) // wrong forward qqx - && match_expectation(type, {"g","g"}, {"g","-2","1","g"}) // wrong central qqx - ; - } - - // Two boson states, that are currently not implemented - bool check_bad_FS(){ - auto type{ HEJ::event_type::bad_final_state}; - return - match_expectation(type, {"g","g"}, {"g","h","h","g"}) - && match_expectation(type, {"g","g"}, {"h","g","h","g"}) - && match_expectation(type, {"g","-1"}, {"g","h","Wp","-2"}) - && match_expectation(type, {"-3","-1"},{"-4","g","Wp","Wp","-2"}) - && match_expectation(type, {"-4","-1"},{"-3","Wp","g","Wm","-2"}) - && match_expectation(type, {"-4","-1"},{"g","-3","Wp","Wm","-2"}) - ; - } -} - -int main() { - // tests for "no false negatives" - // i.e. all HEJ-configurations get classified correctly - if(!check_fkl()) return EXIT_FAILURE; - if(!check_uno()) return EXIT_FAILURE; - if(!check_extremal_qqx()) return EXIT_FAILURE; - if(!check_central_qqx()) return EXIT_FAILURE; - // test for "no false positive" - // i.e. non-HEJ gives non-HEJ - if(!check_non_HEJ()) return EXIT_FAILURE; - if(!check_bad_FS()) return EXIT_FAILURE; - //! @TODO missing: - //! checks for partons sharing a jet - - return EXIT_SUCCESS; -} diff --git a/t/test_classify.cc b/t/test_classify_ref.cc similarity index 100% copy from t/test_classify.cc copy to t/test_classify_ref.cc