diff --git a/FixedOrderGen/t/PSP_subl.cc b/FixedOrderGen/t/PSP_subl.cc index d41bf08..fc2846c 100644 --- a/FixedOrderGen/t/PSP_subl.cc +++ b/FixedOrderGen/t/PSP_subl.cc @@ -1,220 +1,221 @@ /** * check that each subprocess xs is correctly generated when only selecting one * * \authors The HEJ collaboration (see AUTHORS for details) * \date 2020 * \copyright GPLv2 or later */ #include #include #include #include #include "HEJ/Mixmax.hh" #include "HEJ/Event.hh" #include "HEJ/CrossSectionAccumulator.hh" #include "config.hh" #include "EventGenerator.hh" //! throw error if condition not fulfilled #define ASSERT(x) if(!(x)) { \ throw std::logic_error("Assertion '" #x "' failed."); \ } //! throw error if condition not fulfilled #define ASSERT_THROW(x, exception) try { \ x; \ std::cerr << "'" #x "' did not throw an exception.\n"; \ throw; \ } catch(exception const & ex){ \ std::cout << "throw triggered: " << ex.what() << std::endl; \ } \ catch (...) { \ std::cerr << "Unexpected exception thrown for '" #x "'.\n"; \ throw; \ } namespace { const static std::array ALL_TYPES{ HEJ::event_type::FKL, HEJ::event_type::unordered_backward, HEJ::event_type::unordered_forward, HEJ::event_type::extremal_qqxb, HEJ::event_type::extremal_qqxf, HEJ::event_type::central_qqx }; HEJFOG::EventGenerator make_generator( HEJFOG::Config const & config, std::shared_ptr ran ){ return HEJFOG::EventGenerator{ 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 }; } bool valid_type( HEJFOG::Subleading const channels, HEJ::event_type::EventType type ){ using namespace HEJ::event_type; using c = HEJFOG::subleading::Channels; if(channels.none()) return type == FKL; if(channels.count()!=1) return false; if(channels[c::uno]) return type == unob || type == unof; if(channels[c::eqqx]) return type == qqxexb || type == qqxexf; if(channels[c::cqqx]) return type == qqxmid; throw HEJ::unknown_option{"wrong channel"}; } void generate_till_throw(HEJFOG::EventGenerator & gen ){ for(std::size_t i=0; i<100; ++i){ auto ev = gen.gen_event(); if(gen.status()==HEJFOG::Status::good){ std::cerr << "Wrongfully generated valid event!" << *ev <<"\n"; throw; } } std::cerr << "Unable to generate a proper throw!\n"; throw; } } int main(int argc, char const *argv[]) { if(argc != 2 && argc != 3){ std::cerr << "Usage: " << argv[0] << " config.yaml\n"; return EXIT_FAILURE; } const bool short_only = argc==3; std::cout <(); if(short_only) config.events/=10.; // mixes sample HEJ::CrossSectionAccumulator xs_tot; config.process.incoming[0] = config.process.incoming[1] = HEJ::ParticleID::proton; config.subleading_fraction=0.8; if(config.process.boson && *config.process.boson == HEJ::ParticleID::Higgs){ config.subleading_channels.reset(); config.subleading_channels.set(HEJFOG::subleading::uno); } else { config.subleading_channels.set(); } { HEJFOG::EventGenerator gen = make_generator(config, ran); for(std::size_t i=0; icentral().weight /= config.events; xs_tot.fill(*ev); } } ASSERT(xs_tot.total().value!=0.); } // config.events /= HEJFOG::subleading::last+1; // pure FKL HEJ::CrossSectionAccumulator xs_subl; { config.subleading_fraction = 0.; HEJFOG::EventGenerator gen = make_generator(config, ran); for(std::size_t i=0; icentral().weight /= config.events; xs_subl.fill(*ev); ASSERT(valid_type(0,ev->type())); } } ASSERT(xs_subl.total().value!=0.); std::cout << "=>\n" << xs_subl << std::endl; } // pure subleading config.subleading_fraction = 1.; for(unsigned channel = HEJFOG::subleading::first; channel <= HEJFOG::subleading::last; ++channel ){ if(config.process.njets < 4 && channel == HEJFOG::subleading::cqqx) continue; config.subleading_channels.reset(); config.subleading_channels.set(channel); HEJFOG::EventGenerator gen = make_generator(config, ran); HEJ::CrossSectionAccumulator xs_channel; std::cout << config.subleading_channels << " " <type()==HEJ::event_type::FKL) continue; ev->central().weight /= config.events; xs_subl.fill(*ev); xs_channel.fill(*ev); ASSERT(valid_type(config.subleading_channels,ev->type())); } } ASSERT(xs_subl.total().value!=0.); std::cout << "=>\n" << xs_channel << std::endl; } std::cout << "Total:\n" << xs_tot << " vs.\n" << xs_subl << std::endl; + const double max_sigma = short_only?3.:2.; for(auto type: ALL_TYPES){ double diff = 0.; double err = 1.; try { auto const & tot = xs_tot[type]; auto const & subl = xs_subl[type]; diff = tot.value - subl.value; err = sqrt(tot.error+subl.error); } catch (std::out_of_range const &){ std::cout << name(type) << " not set" << std::endl; ASSERT_THROW(xs_tot[type], std::out_of_range); ASSERT_THROW(xs_subl[type], std::out_of_range); continue; } - if(std::abs(diff) > 2.*err){ + if(std::abs(diff) > max_sigma*err){ std::cerr << "Large difference in " << name(type) << " (" << (diff/err) << " sigma)\n"; return EXIT_FAILURE; } } return EXIT_SUCCESS; }