diff --git a/t/test_classify_new.cc b/t/test_classify_new.cc index b355551..2bde163 100644 --- a/t/test_classify_new.cc +++ b/t/test_classify_new.cc @@ -1,380 +1,380 @@ /** * \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, 8> all_quarks{"-4","-3","-2","-1","1","2","3","4"}; const std::array<std::string, 3> all_bosons{"h", "Wp", "Wm"}; 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); } // 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){ const int W_charge = abs(HEJ::to_ParticleID(boson))>0?1:-1; auto qflav{ HEJ::to_ParticleID(quark) }; if(W_charge*qflav > 0 && qflav%2 == 1) return false; if(W_charge*qflav < 0 && abs(qflav%2) == 0) return false; 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_AWZH_boson(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); auto const clustered{ ev.cluster(jet_def, min_jet_pt) }; ASSERT(clustered.jets().size() == njets); return clustered; } 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::names[expected] << " but found " << HEJ::event_type::names[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_quarks) // all quark flavours for(std::string const & last: all_quarks){ 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 static std::mt19937_64 ran{0}; 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_quarks){ 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?1:0] = uno; - base_in[i?0:1] = fkl; - base_out[fkl_pos] = uno; - base_out[uno_pos] = fkl; + 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 inside FKL chain for(int pos=i?(uno_pos+1):fkl_pos; pos<=(i?(fkl_pos+1):uno_pos); ++pos){ auto in{base_in}; auto out{base_out}; // change quark flavours for W static std::mt19937_64 ran{0}; int 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; } } int main() { if(!check_fkl()) return EXIT_FAILURE; if(!check_uno()) return EXIT_FAILURE; //TODO next: // generate a bunch of test configurations return EXIT_SUCCESS; }