Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8724499
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Subscribers
None
View Options
diff --git a/include/HEJ/EventReweighter.hh b/include/HEJ/EventReweighter.hh
index b6b1c2d..b183a91 100644
--- a/include/HEJ/EventReweighter.hh
+++ b/include/HEJ/EventReweighter.hh
@@ -1,190 +1,190 @@
/** \file
* \brief Declares the EventReweighter class
*
* EventReweighter is the main class used within HEJ 2. It reweights the
* resummation events.
*
* \authors Jeppe Andersen, Tuomas Hapola, Marian Heil, Andreas Maier, Jennifer Smillie
* \date 2019
* \copyright GPLv2 or later
*/
#pragma once
#include <array>
#include <functional>
#include <utility>
#include <vector>
#include "HEJ/config.hh"
#include "HEJ/event_types.hh"
#include "HEJ/MatrixElement.hh"
#include "HEJ/PDF.hh"
#include "HEJ/PDG_codes.hh"
#include "HEJ/RNG.hh"
#include "HEJ/ScaleFunction.hh"
+#include "HEJ/Weights.hh"
namespace LHEF {
class HEPRUP;
}
namespace HEJ{
class Event;
- class Weights;
//! Beam parameters
/**
* Currently, only symmetric beams are supported,
* so there is a single beam energy.
*/
struct Beam{
double E; /**< Beam energy */
std::array<ParticleID, 2> type; /**< Beam particles */
};
//! Main class for reweighting events in HEJ.
class EventReweighter{
using EventType = event_type::EventType;
public:
EventReweighter(
Beam beam, /**< Beam Energy */
int pdf_id, /**< PDF ID */
ScaleGenerator scale_gen, /**< Scale settings */
EventReweighterConfig conf, /**< Configuration parameters */
HEJ::RNG & ran /**< Random number generator */
);
EventReweighter(
LHEF::HEPRUP const & heprup, /**< LHEF event header */
ScaleGenerator scale_gen, /**< Scale settings */
EventReweighterConfig conf, /**< Configuration parameters */
HEJ::RNG & ran /**< Random number generator */
);
//! Get the used pdf
PDF const & pdf() const;
//! Generate resummation events for a given fixed-order event
/**
* @param ev Fixed-order event corresponding
* to the resummation events
* @param num_events Number of trial resummation configurations.
* @returns A vector of resummation events.
*
* The result vector depends on the type of the input event and the
* treatment of different types as specified in the constructor:
*
* \ref reweight The result vector contains between
* 0 and num_events resummation events.
*
* \ref keep If the input event passes the resummation jet cuts
* the result vector contains one event. Otherwise it is empty.
*
* \ref discard The result vector is empty
*/
std::vector<Event> reweight(
Event const & ev,
int num_events
);
private:
template<typename... T>
PDF const & pdf(T&& ...);
/** \internal
* \brief main generation/reweighting function:
* generate phase space points and divide out Born factors
*/
std::vector<Event> gen_res_events(
Event const & ev, int num_events
);
std::vector<Event> rescale(
Event const & Born_ev, std::vector<Event> events
) const;
/** \internal
* \brief Do the Jets pass the resummation Cuts?
*
* @param ev Event in Question
* @returns 0 or 1 depending on if ev passes Jet Cuts
*/
bool jets_pass_resummation_cuts(Event const & ev) const;
/** \internal
* \brief pdf_factors Function
*
* @param ev Event in Question
* @returns EventFactor due to PDFs
*
* Calculates the Central value and the variation due
* to the PDF choice made.
*/
Weights pdf_factors(Event const & ev) const;
/** \internal
* \brief matrix_elements Function
*
* @param ev Event in question
* @returns EventFactor due to MatrixElements
*
* Calculates the Central value and the variation due
* to the Matrix Element.
*/
Weights matrix_elements(Event const & ev) const;
/** \internal
* \brief Scale-dependent part of fixed-order matrix element
*
* @param ev Event in question
* @returns EventFactor scale variation due to FO-ME.
*
* This is only called to compute the scale variation for events where
* we don't do resummation (e.g. non-FKL).
* Since at tree level the scale dependence is just due to alpha_s,
* it is enough to return the alpha_s(mur) factors in the matrix element.
* The rest drops out in the ratio of (output event ME)/(input event ME),
* so we never have to compute it.
*/
Weights fixed_order_scale_ME(Event const & ev) const;
/** \internal
* \brief Computes the tree level matrix element
*
* @param ev Event in Question
* @returns HEJ approximation to Tree level Matrix Element
*
* This computes the HEJ approximation to the tree level FO
* Matrix element which is used within the LO weighting process.
*/
double tree_matrix_element(Event const & ev) const;
//! \internal General parameters
EventReweighterConfig param_;
//! \internal Beam energy
double E_beam_;
//! \internal PDF
PDF pdf_;
//! \internal Object to calculate the square of the matrix element
MatrixElement MEt2_;
//! \internal Object to calculate event renormalisation and factorisation scales
ScaleGenerator scale_gen_;
/** \internal random number generator
*
* \note We use a reference_wrapper so that EventReweighter objects can
* still be copied (which would be impossible with a reference).
*/
std::reference_wrapper<HEJ::RNG> ran_;
};
template<typename... T>
PDF const & EventReweighter::pdf(T&&... t){
return pdf_ = PDF{std::forward<T>(t)...};
}
}
diff --git a/include/HEJ/Weights.hh b/include/HEJ/Weights.hh
index fd34e92..8de138e 100644
--- a/include/HEJ/Weights.hh
+++ b/include/HEJ/Weights.hh
@@ -1,49 +1,97 @@
/** \file
- * \brief Container for event weights
+ * \brief Container for event Weights
*
* \authors Jeppe Andersen, Tuomas Hapola, Marian Heil, Andreas Maier, Jennifer Smillie
* \date 2019
* \copyright GPLv2 or later
*/
#pragma once
+#include "HEJ/exceptions.hh"
+
#include <vector>
namespace HEJ{
- //! Collection of weights assigned to a single event
+ //! Collection of parameters, e.g. Weights, assigned to a single event
/**
- * A number of member functions of the MatrixElement class return Weights
+ * A number of member functions of the MatrixElement class return Parameters
* objects containing the squares of the matrix elements for the various
* scale choices.
*/
- struct Weights {
- double central;
- std::vector<double> variations;
-
- Weights& operator*=(Weights const & other);
- Weights& operator*=(double factor);
- Weights& operator/=(Weights const & other);
- Weights& operator/=(double factor);
+ template<class T>
+ struct Parameters {
+ T central;
+ std::vector<T> variations;
+
+ template<class T_ext>
+ Parameters<T>& operator*=(Parameters<T_ext> const & other);
+ Parameters<T>& operator*=(double factor);
+ template<class T_ext>
+ Parameters<T>& operator/=(Parameters<T_ext> const & other);
+ Parameters<T>& operator/=(double factor);
};
- inline
- Weights operator*(Weights a, Weights const & b) {
+ template<class T1, class T2> inline
+ Parameters<T1> operator*(Parameters<T1> a, Parameters<T2> const & b) {
return a*=b;
}
- inline
- Weights operator*(Weights a, double b) {
+ template<class T> inline
+ Parameters<T> operator*(Parameters<T> a, double b) {
return a*=b;
}
- inline
- Weights operator*(double b, Weights a) {
+ template<class T> inline
+ Parameters<T> operator*(double b, Parameters<T> a) {
return a*=b;
}
- inline
- Weights operator/(Weights a, Weights const & b) {
+ template<class T1, class T2> inline
+ Parameters<T1> operator/(Parameters<T1> a, Parameters<T2> const & b) {
return a/=b;
}
- inline
- Weights operator/(Weights a, double b) {
+ template<class T> inline
+ Parameters<T> operator/(Parameters<T> a, double b) {
return a/=b;
}
+
+ //! Shortcut for Weights, e.g. used by the MatrixElement
+ using Weights = Parameters<double>;
+
+ template<class T>
+ template<class T_ext>
+ Parameters<T>& Parameters<T>::operator*=(Parameters<T_ext> const & other) {
+ if(other.variations.size() != variations.size()) {
+ throw std::invalid_argument{"Wrong number of Parameters"};
+ }
+ central *= other.central;
+ for(std::size_t i = 0; i < variations.size(); ++i) {
+ variations[i] *= other.variations[i];
+ }
+ return *this;
+ };
+
+ template<class T>
+ Parameters<T>& Parameters<T>::operator*=(double factor) {
+ central *= factor;
+ for(auto & wt: variations) wt *= factor;
+ return *this;
+ };
+
+ template<class T>
+ template<class T_ext>
+ Parameters<T>& Parameters<T>::operator/=(Parameters<T_ext> const & other) {
+ if(other.variations.size() != variations.size()) {
+ throw std::invalid_argument{"Wrong number of Parameters"};
+ }
+ central /= other.central;
+ for(std::size_t i = 0; i < variations.size(); ++i) {
+ variations[i] /= other.variations[i];
+ }
+ return *this;
+ };
+
+ template<class T>
+ Parameters<T>& Parameters<T>::operator/=(double factor) {
+ central /= factor;
+ for(auto & wt: variations) wt /= factor;
+ return *this;
+ };
}
diff --git a/src/EventReweighter.cc b/src/EventReweighter.cc
index c888370..a23923e 100644
--- a/src/EventReweighter.cc
+++ b/src/EventReweighter.cc
@@ -1,275 +1,274 @@
/**
* \authors Jeppe Andersen, Tuomas Hapola, Marian Heil, Andreas Maier, Jennifer Smillie
* \date 2019
* \copyright GPLv2 or later
*/
#include "HEJ/EventReweighter.hh"
#include <algorithm>
#include <assert.h>
#include <limits>
#include <math.h>
#include <stddef.h>
#include <string>
#include <unordered_map>
#include "fastjet/ClusterSequence.hh"
#include "LHEF/LHEF.h"
#include "HEJ/Event.hh"
#include "HEJ/exceptions.hh"
#include "HEJ/Particle.hh"
#include "HEJ/PDG_codes.hh"
#include "HEJ/PhaseSpacePoint.hh"
-#include "HEJ/Weights.hh"
namespace HEJ{
using EventType = event_type::EventType;
namespace {
static_assert(
std::numeric_limits<double>::has_quiet_NaN,
"no quiet NaN for double"
);
constexpr double NaN = std::numeric_limits<double>::quiet_NaN();
EventData to_EventData(PhaseSpacePoint const & psp){
EventData result;
result.incoming() = psp.incoming();
std::sort(
begin(result.incoming()), end(result.incoming()),
[](Particle o1, Particle o2){return o1.p.pz()<o2.p.pz();}
);
assert(result.incoming().size() == 2);
result.outgoing() = psp.outgoing();
assert(
std::is_sorted(
begin(result.outgoing()), end(result.outgoing()),
rapidity_less{}
)
);
assert(result.outgoing().size() >= 2);
result.decays() = psp.decays();
result.central().mur = NaN;
result.central().muf = NaN;
result.central().weight = psp.weight();
return result;
}
} // namespace anonymous
EventReweighter::EventReweighter(
LHEF::HEPRUP const & heprup,
ScaleGenerator scale_gen,
EventReweighterConfig conf,
HEJ::RNG & ran
):
EventReweighter{
HEJ::Beam{
heprup.EBMUP.first,
{{
static_cast<HEJ::ParticleID>(heprup.IDBMUP.first),
static_cast<HEJ::ParticleID>(heprup.IDBMUP.second)
}}
},
heprup.PDFSUP.first,
std::move(scale_gen),
std::move(conf),
ran
}
{
if(heprup.EBMUP.second != E_beam_){
throw std::invalid_argument(
"asymmetric beam: " + std::to_string(E_beam_)
+ " ---> <--- " + std::to_string(heprup.EBMUP.second)
);
};
if(heprup.PDFSUP.second != pdf_.id()){
throw std::invalid_argument(
"conflicting PDF ids: " + std::to_string(pdf_.id())
+ " vs. " + std::to_string(heprup.PDFSUP.second)
);
}
}
EventReweighter::EventReweighter(
Beam beam,
int pdf_id,
ScaleGenerator scale_gen,
EventReweighterConfig conf,
HEJ::RNG & ran
):
param_{std::move(conf)},
E_beam_{beam.E},
pdf_{pdf_id, beam.type.front(), beam.type.back()},
MEt2_{
[this](double mu){ return pdf_.Halphas(mu); },
param_.ME_config
},
scale_gen_(std::move(scale_gen)),
ran_{ran}
{}
PDF const & EventReweighter::pdf() const{
return pdf_;
}
std::vector<Event> EventReweighter::reweight(
Event const & input_ev, int num_events
){
auto res_events = gen_res_events(input_ev, num_events);
if(res_events.empty()) return {};
for(auto & event: res_events) event = scale_gen_(event);
return rescale(input_ev, std::move(res_events));
}
std::vector<Event> EventReweighter::gen_res_events(
Event const & ev,
int phase_space_points
){
assert(ev.variations().empty());
switch(param_.treat.at(ev.type())){
case EventTreatment::discard: return {};
case EventTreatment::keep:
if(! jets_pass_resummation_cuts(ev)) return {};
else return {ev};
default:;
}
const double Born_shat = shat(ev);
std::vector<Event> resummation_events;
for(int psp_number = 0; psp_number < phase_space_points; ++psp_number){
PhaseSpacePoint psp{ev, param_.psp_config, ran_};
if(psp.weight() == 0.) continue;
if(psp.incoming()[0].E() > E_beam_ || psp.incoming()[1].E() > E_beam_) continue;
resummation_events.emplace_back(
to_EventData(std::move(psp)),
param_.jet_param.def, param_.jet_param.min_pt
);
auto & new_event = resummation_events.back();
assert(new_event.variations().empty());
new_event.central().mur = ev.central().mur;
new_event.central().muf = ev.central().muf;
const double resum_shat = shat(new_event);
new_event.central().weight *= ev.central().weight*Born_shat*Born_shat/
(phase_space_points*resum_shat*resum_shat);
}
return resummation_events;
}
std::vector<Event> EventReweighter::rescale(
Event const & Born_ev,
std::vector<Event> events
) const{
const double Born_pdf = pdf_factors(Born_ev).central;
const double Born_ME = tree_matrix_element(Born_ev);
for(auto & cur_event: events){
const auto pdf = pdf_factors(cur_event);
assert(pdf.variations.size() == cur_event.variations().size());
const auto ME = matrix_elements(cur_event);
assert(ME.variations.size() == cur_event.variations().size());
cur_event.central().weight *= pdf.central*ME.central/(Born_pdf*Born_ME);
for(size_t i = 0; i < cur_event.variations().size(); ++i){
cur_event.variations(i).weight *=
pdf.variations[i]*ME.variations[i]/(Born_pdf*Born_ME);
}
}
return events;
};
bool EventReweighter::jets_pass_resummation_cuts(
Event const & ev
) const{
const auto out_as_PseudoJet = to_PseudoJet(filter_partons(ev.outgoing()));
fastjet::ClusterSequence cs{out_as_PseudoJet, param_.jet_param.def};
return cs.inclusive_jets(param_.jet_param.min_pt).size() == ev.jets().size();
}
Weights
EventReweighter::pdf_factors(Event const & ev) const{
auto const & a = ev.incoming().front();
auto const & b = ev.incoming().back();
const double xa = a.p.e()/E_beam_;
const double xb = b.p.e()/E_beam_;
Weights result;
std::unordered_map<double, double> known_pdf;
result.central =
pdf_.pdfpt(0,xa,ev.central().muf,a.type)*
pdf_.pdfpt(1,xb,ev.central().muf,b.type);
known_pdf.emplace(ev.central().muf, result.central);
result.variations.reserve(ev.variations().size());
for(auto const & ev_param: ev.variations()){
const double muf = ev_param.muf;
auto cur_pdf = known_pdf.find(muf);
if(cur_pdf == known_pdf.end()){
cur_pdf = known_pdf.emplace(
muf,
pdf_.pdfpt(0,xa,muf,a.type)*pdf_.pdfpt(1,xb,muf,b.type)
).first;
}
result.variations.emplace_back(cur_pdf->second);
}
assert(result.variations.size() == ev.variations().size());
return result;
}
Weights
EventReweighter::matrix_elements(Event const & ev) const{
assert(param_.treat.count(ev.type()) > 0);
if(param_.treat.find(ev.type())->second == EventTreatment::keep){
return fixed_order_scale_ME(ev);
}
return MEt2_(ev);
}
double EventReweighter::tree_matrix_element(Event const & ev) const{
assert(ev.variations().empty());
assert(param_.treat.count(ev.type()) > 0);
if(param_.treat.find(ev.type())->second == EventTreatment::keep){
return fixed_order_scale_ME(ev).central;
}
return MEt2_.tree(ev).central;
}
Weights
EventReweighter::fixed_order_scale_ME(Event const & ev) const{
int alpha_s_power = 0;
for(auto const & part: ev.outgoing()){
if(is_parton(part))
++alpha_s_power;
else {
switch(part.type){
case pid::Higgs: {
alpha_s_power += 2;
break;
}
// TODO
case pid::Wp:
case pid::Wm:
case pid::photon:
case pid::Z:
default:
throw not_implemented("Emission of boson of unsupported type");
}
}
}
Weights result;
result.central = pow(pdf_.Halphas(ev.central().mur), alpha_s_power);
for(auto const & var: ev.variations()){
result.variations.emplace_back(
pow(pdf_.Halphas(var.mur), alpha_s_power)
);
}
return result;
}
} // namespace HEJ
diff --git a/src/Weights.cc b/src/Weights.cc
deleted file mode 100644
index de2d561..0000000
--- a/src/Weights.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * \authors Jeppe Andersen, Tuomas Hapola, Marian Heil, Andreas Maier, Jennifer Smillie
- * \date 2019
- * \copyright GPLv2 or later
- */
-#include "HEJ/Weights.hh"
-
-#include <stdexcept>
-
-namespace HEJ {
-
- Weights& Weights::operator*=(Weights const & other) {
- if(other.variations.size() != variations.size()) {
- throw std::invalid_argument{"Wrong number of weights"};
- }
- central *= other.central;
- for(std::size_t i = 0; i < variations.size(); ++i) {
- variations[i] *= other.variations[i];
- }
- return *this;
- }
-
- Weights& Weights::operator*=(double factor) {
- central *= factor;
- for(auto & wt: variations) wt *= factor;
- return *this;
- }
-
- Weights& Weights::operator/=(Weights const & other) {
- if(other.variations.size() != variations.size()) {
- throw std::invalid_argument{"Wrong number of weights"};
- }
- central /= other.central;
- for(std::size_t i = 0; i < variations.size(); ++i) {
- variations[i] /= other.variations[i];
- }
- return *this;
- }
-
- Weights& Weights::operator/=(double factor) {
- central /= factor;
- for(auto & wt: variations) wt /= factor;
- return *this;
- }
-
-}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Jan 20, 11:34 PM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4242905
Default Alt Text
(19 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment