Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F9514797
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
16 KB
Subscribers
None
View Options
diff --git a/FixedOrderGen/src/EventGenerator.cc b/FixedOrderGen/src/EventGenerator.cc
index 796c75f..3b9bde9 100644
--- a/FixedOrderGen/src/EventGenerator.cc
+++ b/FixedOrderGen/src/EventGenerator.cc
@@ -1,127 +1,246 @@
/**
* \authors The HEJ collaboration (see AUTHORS for details)
* \date 2019-2020
* \copyright GPLv2 or later
*/
#include "EventGenerator.hh"
+#include <HEJ/Particle.hh>
#include <cstddef>
+#include <iostream>
+#include <stdexcept>
#include <utility>
#include "HEJ/Config.hh"
#include "HEJ/EWConstants.hh"
#include "HEJ/Event.hh"
#include "HEJ/HiggsCouplingSettings.hh"
#include "HEJ/event_types.hh"
#include "HEJ/exceptions.hh"
#include "HEJ/make_RNG.hh"
+#include "HEJ/PDG_codes.hh"
#include "Beam.hh"
#include "JetParameters.hh"
#include "PhaseSpacePoint.hh"
#include "Process.hh"
+#include "Subleading.hh"
+#include "Utility.hh"
#include "config.hh"
namespace HEJFOG {
+ namespace {
+
+ bool allows_gluon(const HEJ::ParticleID particle_id) {
+ return
+ std::abs(particle_id) == HEJ::pid::proton
+ || particle_id == HEJ::pid::gluon;
+ }
+
+ bool allows_anyquark(const HEJ::ParticleID particle_id) {
+ return
+ std::abs(particle_id) == HEJ::pid::proton
+ || HEJ::is_anyquark(particle_id);
+ }
+
+ Subleading possible_subl_channels(Process const &process) {
+ std::size_t nhiggs_bosons =
+ (process.boson && *process.boson == HEJ::pid::Higgs) ? 1 : 0;
+ if(process.njets + nhiggs_bosons <= 2){
+ return subleading::NONE;
+ }
+ auto allowed = subleading::ALL;
+ if(process.njets + nhiggs_bosons < 4){
+ allowed.reset(subleading::central_qqbar);
+ }
+ if(
+ !allows_gluon(process.incoming[0])
+ && !allows_gluon(process.incoming[1])
+ ){
+ allowed.reset(subleading::extremal_qqbar);
+ }
+
+ if(
+ !allows_anyquark(process.incoming[0])
+ && !allows_anyquark(process.incoming[1])
+ ){
+ allowed.reset(subleading::unordered);
+ }
+
+ if(
+ process.boson && std::abs(*process.boson) == HEJ::pid::Wp
+ && !vector_boson_can_couple_to(process.incoming[0], *process.boson)
+ && !vector_boson_can_couple_to(process.incoming[1], *process.boson)
+ ){
+ allowed.reset(subleading::unordered);
+ }
+ return allowed;
+ }
+
+ bool can_generate_FKL(Process const &process) {
+ std::size_t nhiggs_bosons =
+ (process.boson && *process.boson == HEJ::pid::Higgs) ? 1 : 0;
+ if(process.njets + nhiggs_bosons < 2){
+ return false;
+ }
+ if(
+ is_AWZ_process(process)
+ && !vector_boson_can_couple_to(process.incoming[0], *process.boson)
+ && !vector_boson_can_couple_to(process.incoming[1], *process.boson)
+ ) return false;
+ return true;
+ }
+
+ // TODO: maybe we don't even want to accept inconsistent settings here
+ void ensure_valid_subl(
+ Process const &process,
+ double &subl_chance,
+ Subleading &subl_channels
+ ){
+ if(subl_chance == 0. && subl_channels.any()) {
+ std::cerr << "WARNING: Subleading fraction is set to 0,"
+ " disabling all subleading channels\n";
+ subl_channels = subleading::NONE;
+ }
+ const Subleading possible_channels = possible_subl_channels(process);
+ for (
+ unsigned channel = subleading::Channels::first;
+ channel <= subleading::Channels::last;
+ ++channel
+ ){
+ if(subl_channels.test(channel) && !possible_channels.test(channel)){
+ std::cerr
+ << "WARNING: selected subleading channel "
+ << name(static_cast<subleading::Channels>(channel))
+ << " cannot be generated for the chosen process.\n";
+ subl_channels.reset(channel);
+ }
+ }
+ if(subl_channels == subleading::NONE && subl_chance > 0.) {
+ if(subl_chance == 1.) {
+ throw std::invalid_argument{
+ "Cannot generate subleading event configurations"
+ };
+ }
+ std::cerr <<
+ "WARNING: Positive fraction of subleading configurations requested,"
+ " but cannot generate any.\n";
+ subl_chance = 0.;
+ }
+ if(!can_generate_FKL(process) && subl_chance < 1.) {
+ if(subl_chance > 0.) {
+ std::cerr <<
+ "WARNING: Can only generate subleading configurations.\n";
+ subl_chance = 1.;
+ } else {
+ throw std::invalid_argument{
+ "Cannot generate events for given process"
+ };
+ }
+ }
+ }
+ }
+
EventGenerator::EventGenerator(Config const & config):
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,
config.nlo,
HEJ::make_RNG(config.rng.name, config.rng.seed)
}
{}
EventGenerator::EventGenerator(
Process process,
Beam beam,
HEJ::ScaleGenerator scale_gen,
JetParameters jets,
int pdf_id,
double subl_chance,
Subleading subl_channels,
ParticlesDecayMap particle_decays,
HEJ::HiggsCouplingSettings Higgs_coupling,
HEJ::EWConstants ew_parameters,
HEJ::NLOConfig nlo,
std::shared_ptr<HEJ::RNG> ran
):
pdf_{pdf_id, beam.particles[0], beam.particles[1]},
ME_{
[this](double mu){ return pdf_.Halphas(mu); },
HEJ::MatrixElementConfig{
false,
std::move(Higgs_coupling),
ew_parameters,
nlo
}
},
scale_gen_{std::move(scale_gen)},
process_{std::move(process)},
jets_{std::move(jets)},
beam_{std::move(beam)},
status_{Status::good},
subl_chance_{subl_chance},
subl_channels_{subl_channels},
particle_decays_{std::move(particle_decays)},
ew_parameters_{ew_parameters},
ran_{std::move(ran)}
{
+ ensure_valid_subl(process_, subl_chance_, subl_channels_);
assert(ran_ != nullptr);
}
std::optional<HEJ::Event> EventGenerator::gen_event(){
HEJFOG::PhaseSpacePoint psp{
process_,
jets_,
pdf_, beam_.energy,
subl_chance_, subl_channels_,
particle_decays_,
ew_parameters_,
*ran_
};
status_ = psp.status();
if(status_ != Status::good) return {};
HEJ::Event ev = scale_gen_(
HEJ::Event{
to_EventData( std::move(psp) ).cluster( jets_.def, jets_.min_pt)
}
);
if(!is_resummable(ev.type())){
throw HEJ::not_implemented("Tried to generate a event type, "
"which is not yet implemented in HEJ.");
}
ev.generate_colours(*ran_);
const double shat = HEJ::shat(ev);
const double xa = (ev.incoming()[0].E()-ev.incoming()[0].pz())/(2.*beam_.energy);
const double xb = (ev.incoming()[1].E()+ev.incoming()[1].pz())/(2.*beam_.energy);
// evaluate matrix element
ev.parameters() *= ME_.tree(ev)/(shat*shat);
// and PDFs
ev.central().weight *= pdf_.pdfpt(0,xa,ev.central().muf, ev.incoming()[0].type);
ev.central().weight *= pdf_.pdfpt(0,xb,ev.central().muf, ev.incoming()[1].type);
for(std::size_t i = 0; i < ev.variations().size(); ++i){
auto & var = ev.variations(i);
var.weight *= pdf_.pdfpt(0,xa,var.muf, ev.incoming()[0].type);
var.weight *= pdf_.pdfpt(0,xb,var.muf, ev.incoming()[1].type);
}
return ev;
}
} // namespace HEJFOG
diff --git a/FixedOrderGen/t/PSP_channel.cc b/FixedOrderGen/t/PSP_channel.cc
index 2e9f658..fdec315 100644
--- a/FixedOrderGen/t/PSP_channel.cc
+++ b/FixedOrderGen/t/PSP_channel.cc
@@ -1,250 +1,238 @@
/**
* check that the sum of all possible quarks is the same as a proton
*
* \authors The HEJ collaboration (see AUTHORS for details)
* \date 2020
* \copyright GPLv2 or later
*/
#include <array>
#include <cmath>
#include <iostream>
#include <memory>
#include "HEJ/Mixmax.hh"
#include "HEJ/Event.hh"
#include "config.hh"
#include "EventGenerator.hh"
namespace {
constexpr double max_sigma = 3.6;
}
//! 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<HEJ::ParticleID, 11> PARTONS{
HEJ::ParticleID::g,
HEJ::ParticleID::d, HEJ::ParticleID::u,
HEJ::ParticleID::s, HEJ::ParticleID::c,
HEJ::ParticleID::b,
HEJ::ParticleID::d_bar, HEJ::ParticleID::u_bar,
HEJ::ParticleID::s_bar, HEJ::ParticleID::c_bar,
HEJ::ParticleID::b_bar
};
bool only_channel(
HEJFOG::Subleading channels,
HEJFOG::subleading::Channels selected
){
return channels[selected] && channels.reset(selected).none();
}
- 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;
- }
-
bool can_couple_to_W(HEJ::ParticleID const id, HEJ::ParticleID const boson){
using namespace HEJ;
if(!is_anyquark(id)){
return false;
}
if(std::abs(id)==HEJ::ParticleID::b || std::abs(id)==HEJ::ParticleID::top)
return false;
// Wp:
if(boson>0){
// anti-down
if(id%2==0){
return is_quark(id);
}
// or up-type quark
return is_antiquark(id);
}
// Wm:
// down
if(id%2==0){
return is_antiquark(id);
}
// or anti-up-type quark
return is_quark(id);
}
bool can_couple_to_Z(HEJ::ParticleID const id){
using namespace HEJ;
return is_anyquark(id);
}
}
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 <<std::scientific;
auto config = HEJFOG::load_config(argv[1]);
config.events/=2.;
if(short_only)
config.events/=20.;
double tot_weight = 0.;
double tot_err = 0.;
config.process.incoming[0] = config.process.incoming[1] = HEJ::ParticleID::proton;
{
HEJFOG::EventGenerator gen{config};
for(std::size_t i=0; i<config.events; ++i){
auto const ev = gen.gen_event();
if(ev){
if(config.process.boson && *config.process.boson == HEJ::ParticleID::Z_photon_mix){
const auto boson = std::find_if(
begin(ev->outgoing()), end(ev->outgoing()),
[&](HEJ::Particle const & p){ return p.type == *config.process.boson; }
);
if(boson->m() < 81. || boson->m() > 101.){
continue;
}
}
double const wgt = ev->central().weight/config.events;
tot_weight += wgt;
tot_err += wgt*wgt;
}
}
ASSERT(tot_weight!=0.);
}
tot_err = std::sqrt(tot_err);
config.events /= PARTONS.size();
double tot_channels = 0.;
double err_channels = 0.;
for(auto b1: PARTONS){
for(auto b2: PARTONS){
double wgt_channel = 0.;
double err_channel = 0.;
config.process.incoming[0] = b1;
config.process.incoming[1] = b2;
- HEJFOG::EventGenerator gen{config};
std::cout << name(b1) << "+" << name(b2) << " " <<std::flush;
// for pure subleading configurations some setups states should throw
if(config.subleading_fraction == 1.){
if( only_channel(config.subleading_channels, HEJFOG::subleading::uno) ){
if(HEJ::is_gluon(b1) && HEJ::is_gluon(b2)){
std::cout << "uno" << std::endl;
- ASSERT_THROW(generate_till_throw(gen), std::invalid_argument);
+ ASSERT_THROW(HEJFOG::EventGenerator{config}, std::invalid_argument);
continue;
}
}
if( only_channel(config.subleading_channels, HEJFOG::subleading::eqqbar) ){
if(HEJ::is_anyquark(b1) && HEJ::is_anyquark(b2)){
std::cout << "eqqbar" << std::endl;
- ASSERT_THROW(generate_till_throw(gen), std::invalid_argument);
+ ASSERT_THROW(HEJFOG::EventGenerator{config}, std::invalid_argument);
continue;
}
}
}
// for W+jets we need the correct quarks
if(config.process.boson
&& std::abs(*config.process.boson) == HEJ::ParticleID::Wp
){
if(config.process.njets>3
&& config.subleading_fraction>0.
&& config.subleading_channels[HEJFOG::subleading::cqqbar]){
// this will force central qqbar
} else if(config.process.njets>2
&& config.subleading_fraction>0.
&& config.subleading_channels[HEJFOG::subleading::eqqbar]){
// this will force extremal qqbar
} else {
auto const boson = *config.process.boson;
if(!can_couple_to_W(b1, boson)
&& !can_couple_to_W(b2, boson)
){
std::cout << "bad " << name(boson) << std::endl;
- ASSERT_THROW(generate_till_throw(gen), std::invalid_argument);
+ ASSERT_THROW(HEJFOG::EventGenerator{config}, std::invalid_argument);
continue;
}
}
}
// for Z+jets we need quarks
if(config.process.boson && *config.process.boson == HEJ::ParticleID::Z_photon_mix){
if(config.process.njets>3
&& config.subleading_fraction>0.
&& config.subleading_channels[HEJFOG::subleading::cqqbar]){
// this will force central qqbar
} else if(config.process.njets>2
&& config.subleading_fraction>0.
&& config.subleading_channels[HEJFOG::subleading::eqqbar]){
// this will force extremal qqbar
} else {
auto const boson = *config.process.boson;
if(!can_couple_to_Z(b1) && !can_couple_to_Z(b2)
){
std::cout << "bad " << name(boson) << std::endl;
- ASSERT_THROW(generate_till_throw(gen), std::invalid_argument);
+ ASSERT_THROW(HEJFOG::EventGenerator{config}, std::invalid_argument);
continue;
}
}
}
+ // everything else should work
+ HEJFOG::EventGenerator gen{config};
for(std::size_t i=0; i<config.events; ++i){
- // everything else should work
auto const ev = gen.gen_event();
if(ev){
if(config.process.boson && *config.process.boson == HEJ::ParticleID::Z_photon_mix){
const auto boson = std::find_if(
begin(ev->outgoing()), end(ev->outgoing()),
[&](HEJ::Particle const & p){ return p.type == *config.process.boson; }
);
if(boson->m() < 81. || boson->m() > 101.){
continue;
}
}
double const wgt = ev->central().weight/config.events;
wgt_channel += wgt;
err_channel += wgt*wgt;
}
}
ASSERT(wgt_channel!=0.);
tot_channels += wgt_channel;
err_channels += err_channel;
err_channel = std::sqrt(err_channel);
std::cout << "=> " << wgt_channel << " +/- " << err_channel << std::endl;
}
}
err_channels = std::sqrt(err_channels);
std::cout << tot_weight << " +/- " << tot_err
<< " vs. " << tot_channels << " +/- " << err_channels << std::endl;
const double deviation = std::abs(tot_weight - tot_channels) /
sqrt(err_channels*err_channels+tot_err*tot_err);
std::cout << "(" << deviation << " sigma)" << std::endl;
ASSERT(deviation < max_sigma);
return EXIT_SUCCESS;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Feb 24, 6:45 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4493371
Default Alt Text
(16 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment