Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8725497
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
121 KB
Subscribers
None
View Options
diff --git a/include/RHEJ/EventReweighter.hh b/include/RHEJ/EventReweighter.hh
index ef11688..1463f21 100644
--- a/include/RHEJ/EventReweighter.hh
+++ b/include/RHEJ/EventReweighter.hh
@@ -1,189 +1,181 @@
/** \file EventReweighter.hh
* \brief Main class for reweighting events according to the reversed HEJ method
*
* EventReweighter Class is the main class used within RHEJ. It reweights the
* resummation events.
*/
#pragma once
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "LHEF/LHEF.h"
#include "RHEJ/PDF.hh"
#include "RHEJ/utility.hh"
#include "RHEJ/Event.hh"
#include "RHEJ/event_types.hh"
#include "RHEJ/config.hh"
#include "RHEJ/PhaseSpacePoint.hh"
#include "RHEJ/MatrixElement.hh"
namespace RHEJ{
class ScaleGenerator;
/** \struct Beam EventReweighter.hh "include/RHEJ/EventReweighter.hh"
* \brief Beam Struct. Contains beam energy and incoming particle content.
*
* Contains the value of the energy of the beam and the identity of the two incoming Particles
*/
struct Beam{
double E;
std::array<ParticleID, 2> type;
};
/** \class EventReweighter EventReweighter.hh "include/RHEJ/EventReweighter.hh"
* \brief EventReweighter Main class for reweighting events in RHEJ.
*
* This is the class which reweights the resummation phase space points once they have been
* generated by PhaseSpacePoint. This class also handles how many phase space points are generated
* for every fixed order event which is processed.
*/
class EventReweighter{
using EventType = event_type::EventType;
public:
+
EventReweighter(
- Beam beam, /**< Beam Energy */
+ Beam beam, /**< Beam Energy */
int pdf_id, /**< PDF ID */
- fastjet::JetDefinition jet_def, /**< Jet Definition */
- double jetptmin, /**< Jet Pt minimum */
- EventTreatMap treat, /**< Treat??? */
- double extpartonptmin, /**< External Parton Pt Minimum */
- double max_ext_soft_pt_fraction, /**< External Parton Pt Maximum */
- bool log_corr, /**< Log Correct On or Off */
- HiggsCouplingSettings Higgs_coupling
+ Config const & conf /**< Configuration parameters */
);
EventReweighter(
- LHEF::HEPRUP const & heprup, /**< HEPRUP???? */
- fastjet::JetDefinition jet_def, /**< Jet Definition */
- double jetptmin, /**< Jet Pt minimum */
- EventTreatMap treat, /**< Treat??? */
- double extpartonptmin, /**< External Parton Pt Minimum */
- double max_ext_soft_pt_fraction, /**< External Parton Pt Maximum */
- bool log_corr, /**< Log Correct On or Off */
- HiggsCouplingSettings Higgs_coupling
+ LHEF::HEPRUP const & heprup, /**< LHEF event header */
+ Config const & conf /**< Configuration parameters */
);
PDF const & pdf() const; /**< PDF Used */
std::vector<Event> reweight(
Event const & ev, /**< Event For Reweighing */
- int num_events /**< Number of Events */
+ int num_events /**< Number of Events */
);
std::vector<Event> reweight(
Event const & ev, /**< Event For Reweighing */
- int num_events, /**< Number of Events */
+ int num_events, /**< Number of Events */
ScaleGenerator const & gen_scales /**< Generated Scales see config.hh */
);
private:
/** \struct EventFactors EventReweighter.hh "include/RHEJ/EventReweighter.hh"
* \brief EventFactors Struct containing central value and variations
*
* Contains the Central Value and Variation around
*/
struct EventFactors{
double central; /**< Central Value for the Factor */
std::vector<double> variations; /**< Vector of Variations from central value */
};
template<typename... T>
PDF const & pdf(T&& ...);
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;
/**
* \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;
/**
* \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.
*/
EventFactors pdf_factors(Event const & ev) const;
/**
* \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.
*/
EventFactors matrix_elements(Event const & ev) const;
/**
* \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.
*/
EventFactors fixed_order_scale_ME(Event const & ev) const;
/**
* \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;
/**
* \brief Generation of Resummation Phase Space Points
*
* @param ev Event In Question
* @returns Resummation PhaseSpacePoint
*
* Where is this even called? I can't find it with a grep -r in top directory???
*/
PhaseSpacePoint gen_PhaseSpacePoint(Event const & ev) const;
- double extpartonptmin_; /**< External Parton Minimum Pt */
- double max_ext_soft_pt_fraction_; /**< External Parton Maximum Pt fraction */
- double jetptmin_; /**< Jet Pt Minimum threshold */
- double E_beam_; /**< Energy of Beam */
+ const EventReweighterParameters param;
+
+ // const double extpartonptmin_; /**< External Parton Minimum Pt */
+ // const double max_ext_soft_pt_fraction_; /**< External Parton Maximum Pt fraction */
+ // const double jetptmin_; /**< Jet Pt Minimum threshold */
+ const double E_beam_; /**< Energy of Beam */
+
+ // const fastjet::JetDefinition jet_def_; /**< Jet Definition being used */
+ const PDF pdf_; /**< Relevant PDF */
- fastjet::JetDefinition jet_def_; /**< Jet Definition being used */
- PDF pdf_; /**< Relevant PDF */
+ const MatrixElement MEt2_; /**< Matrix Element Object */
+ // const EventTreatMap treat_;
- MatrixElement MEt2_; /**< Matrix Element Object */
- EventTreatMap treat_;
};
template<typename... T>
PDF const & EventReweighter::pdf(T&&... t){
return pdf_ = PDF{std::forward<T>(t)...};
}
}
diff --git a/include/RHEJ/MatrixElement.hh b/include/RHEJ/MatrixElement.hh
index 8da4a3e..f5eb2bc 100644
--- a/include/RHEJ/MatrixElement.hh
+++ b/include/RHEJ/MatrixElement.hh
@@ -1,226 +1,216 @@
/** \file MatrixElement.hh
* \brief The header file which contains the MatrixElement Class
*
* This contains the MatrixElement Class which contains many functions
* used to calculate many different MatrixElements and their components.
*/
#pragma once
#include <functional>
+#include "RHEJ/config.hh"
#include "RHEJ/utility.hh"
#include "RHEJ/HiggsCouplingSettings.hh"
#include "CLHEP/Vector/LorentzVector.h"
namespace RHEJ{
/** \class MatrixElement MatrixElement.hh "include/RHEJ/MatrixElement.hh
* \brief MatrixElement class. Functions for obtaining various ME and components.
*/
class MatrixElement{
public:
/** \brief MatrixElement Constructor
* @param alpha_s Function taking the renormalisation scale
* and returning the strong coupling constant
- * @param jet_def Jet definition for deciding which particles
- * are members of extremal jets
- * @param log_corr Whether to including logarithmic corrections
- * from the running of the coupling
- * @param Hgg_settings Settings for the Higgs coupling to gluons
*/
+
MatrixElement(
std::function<double (double)> alpha_s,
- fastjet::JetDefinition jet_def, double jetptmin,
- bool log_corr,
- HiggsCouplingSettings Hgg_settings
+ Config const & conf
);
/**
* \brief regulated HEJ matrix element
* @param mur Value of the renormalisation scale
* @param incoming Incoming particles
* @param partons Outgoing particles
* @param check_momenta Special treatment for partons inside extremal jets
* @returns The HEJ matrix element including virtual corrections
*
* cf. eq. (22) in \ref Andersen:2011hs
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*
* \internal Relation to standard HEJ Met2: MatrixElement = Met2*shat^2/(pdfta*pdftb)
*/
double operator()(
double mur,
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const;
//! HEJ tree-level matrix element
/**
* @param mur Value of the renormalisation scale
* @param incoming Incoming particles
* @param outgoing Outgoing particles
* @param check_momenta Special treatment for partons inside extremal jets
* @returns The HEJ matrix element without virtual corrections
*
* cf. eq. (22) in \ref Andersen:2011hs
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*/
double tree(
double mur,
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const;
//! HEJ tree-level matrix element - parametric part
/**
* @param mur Value of the renormalisation scale
* @param outgoing Outgoing particles
* @returns The parametric part of the tree matrix element
*
* cf. eq. (22) in \ref Andersen:2011hs
*
* The tree level matrix element factorises into a parametric part
* which depends on the theory parameters (alpha_s and scale)
* and a kinematic part comprising the dependence on the particle momenta
* and colour factors. This function returns the former.
*/
double tree_param(
double mur,
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing
) const;
//! HEJ tree-level matrix element - kinematic part
/**
* @param incoming Incoming particles
* @param partons Outgoing particles
* @param check_momenta Special treatment for partons inside extremal jets
* @returns The kinematic part of the tree matrix element
*
* cf. eq. (22) in \ref Andersen:2011hs
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*
* The tree level matrix element factorises into a parametric part
* which depends on the theory parameters (alpha_s and scale)
* and a kinematic part comprising the dependence on the particle momenta
* and colour factors. This function returns the latter.
*/
double tree_kin(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const;
/**
* \brief Calculates the Virtual Corrections
* @param mur Value of the renormalisation scale
* @param in Incoming particles
* @param out Outgoing particles
* @returns The Virtual Corrections of the Matrix Element
*
* Incoming particles should be ordered by ascending z momentum.
* Outgoing particles should be ordered by ascending rapidity.
*
* The all order virtual corrections to LL in the MRK limit is
* given by replacing 1/t in the scattering amplitude according to the
* lipatov ansatz.
*
* cf. second-to-last line of eq. (22) in \ref Andersen:2011hs
* note that indices are off by one, i.e. out[0].p corresponds to p_1
*/
double virtual_corrections(
double mur,
std::array<Sparticle, 2> const & in,
std::vector<Sparticle> const & out
) const;
private:
/**
* \brief cf. last line of eq. (22) in \ref Andersen:2011hs
* @param mur Value of Renormalisation Scale
* @param q_j ???
* @param lambda ???
*/
double omega0(
double alpha_s, double mur,
fastjet::PseudoJet const & q_j, double lambda
) const;
double tree_kin_jets(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> partons,
bool check_momenta
) const;
double tree_kin_Higgs(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const;
double tree_kin_Higgs_first(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const;
double tree_kin_Higgs_last(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const;
/**
* \brief Higgs inbetween extremal partons.
*
* Note that in the case of unordered emission, the Higgs is *always*
* treated as if in between the extremal (FKL) partons, even if its
* rapidity is outside the extremal parton rapidities
*/
double tree_kin_Higgs_between(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const;
double tree_param_partons(
double alpha_s, double mur,
std::vector<Sparticle> const & partons
) const;
std::vector<int> in_extremal_jet_indices(
std::vector<fastjet::PseudoJet> const & partons
) const;
std::vector<Sparticle> tag_extremal_jet_partons(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> out_partons, bool check_momenta
) const;
double MH2_forwardH(
RHEJ::ParticleID id,
CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector p1in,
CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in,
CLHEP::HepLorentzVector pH,
double t1, double t2
) const;
std::function<double (double)> alpha_s_;
- HiggsCouplingSettings Hgg_settings_;
-
- fastjet::JetDefinition jet_def_;
- double jetptmin_;
-
- bool log_corr_;
+ MartixElementParameters param;
};
}
diff --git a/include/RHEJ/PhaseSpacePoint.hh b/include/RHEJ/PhaseSpacePoint.hh
index 74ea50e..906fe9c 100644
--- a/include/RHEJ/PhaseSpacePoint.hh
+++ b/include/RHEJ/PhaseSpacePoint.hh
@@ -1,163 +1,162 @@
/** \file PhaseSpacePoint.hh
* \brief Contains the PhaseSpacePoint Class
*/
#pragma once
#include <vector>
#include <CLHEP/Random/Randomize.h>
#include <CLHEP/Random/RanluxEngine.h>
#include "RHEJ/utility.hh"
+#include "RHEJ/config.hh"
#include "RHEJ/Event.hh"
#include "RHEJ/Splitter.hh"
namespace RHEJ{
//! A point in resummation phase space
class PhaseSpacePoint{
public:
//! Default PhaseSpacePoint Constructor
PhaseSpacePoint() = default;
//! PhaseSpacePoint Constructor
/**
* @param ev Clustered Jet Event
- * @param jet_def The Jet Definition Used
- * @param jetptmin Minimum Jet Transverse Momentum
- * @param extpartonptmin Minimum Parton Transverse Momentum
- * @param max_ext_soft_pt Maximum Parton Transverse Momentum?
+ * @param conf Configuration parameters
*/
PhaseSpacePoint(
Event const & ev,
- fastjet::JetDefinition jet_def, double jetptmin,
- double extpartonptmin, double max_ext_soft_pt
+ Config const & conf
);
//! Get Weight Function
/**
* @returns Weight of Event
*/
double weight() const{
return weight_;
}
//! Get Incoming Function
/**
* @returns Incoming Particles
*/
std::array<Sparticle, 2> const & incoming() const{
return incoming_;
}
//! Get Outgoing Function
/**
* @returns Outgoing Particles
*/
std::vector<Sparticle> const & outgoing() const{
return outgoing_;
}
std::unordered_map<int, std::vector<Sparticle>> const & decays() const{
return decays_;
}
static constexpr double ccut = 0.2; // universal min pt cut
static constexpr int ng_max = 1000; // maximum number of extra gluons
static void reset_ranlux(std::string const & init_file);
static void reset_ranlux(char const * init_file);
- private:
+ private:
std::vector<fastjet::PseudoJet> cluster_jets(
std::vector<fastjet::PseudoJet> const & partons
) const;
bool pass_resummation_cuts(
std::vector<fastjet::PseudoJet> const & jets
) const;
bool pass_extremal_cuts(
fastjet::PseudoJet const & ext_parton,
fastjet::PseudoJet const & jet
) const;
int sample_ng(std::vector<fastjet::PseudoJet> const & Born_jets);
int sample_ng_jets(int ng, std::vector<fastjet::PseudoJet> const & Born_jets);
double probability_in_jet(
std::vector<fastjet::PseudoJet> const & Born_jets
) const;
std::vector<fastjet::PseudoJet> gen_non_jet(
int ng_non_jet,
double ptmin, double ptmax
);
void rescale_rapidities(
std::vector<fastjet::PseudoJet> & partons,
double ymin, double ymax
);
std::vector<fastjet::PseudoJet> reshuffle(
std::vector<fastjet::PseudoJet> const & Born_jets,
fastjet::PseudoJet const & q
);
bool jets_ok(
std::vector<fastjet::PseudoJet> const & Born_jets,
std::vector<fastjet::PseudoJet> const & partons
) const;
void reconstruct_incoming(std::array<Sparticle, 2> const & Born_incoming);
double phase_space_normalisation(
int num_Born_jets,
int num_res_partons
) const;
std::vector<fastjet::PseudoJet> split(
std::vector<fastjet::PseudoJet> const & jets, int ng_jets
);
std::vector<int> distribute_jet_partons(
int ng_jets, std::vector<fastjet::PseudoJet> const & jets
);
std::vector<fastjet::PseudoJet> split(
std::vector<fastjet::PseudoJet> const & jets,
std::vector<int> const & np_in_jet
);
bool split_preserved_jets(
std::vector<fastjet::PseudoJet> const & jets,
std::vector<fastjet::PseudoJet> const & jet_partons
) const;
template<class Particle>
Particle const & most_backward_FKL(
std::vector<Particle> const & partons
) const;
template<class Particle>
Particle const & most_forward_FKL(
std::vector<Particle> const & partons
) const;
template<class Particle>
Particle & most_backward_FKL(std::vector<Particle> & partons) const;
template<class Particle>
Particle & most_forward_FKL(std::vector<Particle> & partons) const;
bool extremal_ok(
std::vector<fastjet::PseudoJet> const & partons
) const;
void copy_AWZH_boson_from(Event const & event);
bool momentum_conserved(double ep) const;
bool unob_, unof_;
double weight_;
- double extpartonptmin_;
- double max_ext_soft_pt_fraction_;
- double jetptmin_;
- fastjet::JetDefinition jet_def_;
+ // double extpartonptmin_;
+ // double max_ext_soft_pt_fraction_;
+ // double jetptmin_;
+ // fastjet::JetDefinition jet_def_;
+ const PhaseSpacePointParameters param;
+
std::array<Sparticle, 2> incoming_;
std::vector<Sparticle> outgoing_;
//! Particle decays in the format {outgoing index, decay products}
std::unordered_map<int, std::vector<Sparticle>> decays_;
static CLHEP::Ranlux64Engine ran_;
HejSplit splitter_;
};
}
diff --git a/include/RHEJ/config.hh b/include/RHEJ/config.hh
index c8f4962..7082061 100644
--- a/include/RHEJ/config.hh
+++ b/include/RHEJ/config.hh
@@ -1,160 +1,202 @@
/** \file config.hh
* \brief The file which handles the configuration file parameters
*
* Contains the JetParameters Struct and ScaleConfig Struct. Also
* contains the ScaleGenerator Class and the EventTreatment class.
* Config struct is also defined here. The configuration files
* parameters are read and then stored within this objects.
*/
#pragma once
#include <string>
#include <memory>
#include "fastjet/JetDefinition.hh"
#include "yaml-cpp/yaml.h"
#include "RHEJ/event_types.hh"
#include "RHEJ/Event.hh"
#include "RHEJ/HiggsCouplingSettings.hh"
#include "RHEJ/optional.hh"
#include "RHEJ/output_formats.hh"
#include "RHEJ/ScaleFunction.hh"
#include "RHEJ/utility.hh"
namespace RHEJ{
/**! \struct JetParameters config.hh "include/RHEJ/config.hh"
* \brief Contains Jet Definition and Minimum Pt to be a Jet.
*
* Contains the Fastjet definition of a Jet and a threshold (minimum) value for pt
*/
struct JetParameters{
fastjet::JetDefinition def; /**< Jet Definition */
double min_pt; /**< Minimum Jet Pt */
};
/**! \struct ScaleConfig config.hh "include/RHEJ/config.hh"
* \brief Sets up the possible choices for scale variation?
*
* There is a vector which contains the possible scale choices and
* also vector of doubles with the scale factors along with a max
* scale ratio.
*/
struct ScaleConfig{
// std::vector<std::unique_ptr<ScaleFunction>> scales; /**< Vector of possible Scale choices */
std::vector<std::shared_ptr<ScaleFunction>> scales; /**< Vector of possible Scale choices */
std::vector<double> scale_factors; /**< Vector of possible Scale Factors */
double max_scale_ratio; /**< Maximum ratio for the scales */
};
/**! \class ScaleGenerator config.hh "include/RHEJ/config.hh"
* \brief A Class used to generate scales
*
* This class has a clustered event class and scale config struct
* within it.
*/
class ScaleGenerator{
public:
ScaleGenerator() = default;
explicit ScaleGenerator(ScaleConfig && settings):
settings_{std::move(settings)}
{}
Event operator()(Event ev) const;
ScaleConfig const & settings() const;
private:
ScaleConfig settings_;
};
- /**
+ /**! \enum EventTreatment config.hh "include/RHEJ/config.hh"
* \brief Enumeration which deals with how to treat events.
*
* The program will decide on how to treat an event based on
* the value of this enumeration.
*/
enum class EventTreatment{
reweight, /**< Reweigh the event */
keep, /**< Keep the event */
discard, /**< Discard the event */
};
/**
* \brief An ordered Map with EventType keys and mapped values EventTreatment
*
* If called upon with EventTreatMap.at(EventType) it will return the treatment which has
* been specified for that EventType.
*/
using EventTreatMap = std::map<event_type::EventType, EventTreatment>;
- /**! \struct Config config.hh "include/RHEJ/config.hh" \todo{update}
+ /**! \struct Config config.hh "include/RHEJ/config.hh"
* \brief Config Struct for user input parameters.
*
* The struct which handles the input card given by the user.
*
- * \internal To add a new option: \todo{update this list}
+ * \internal To add a new option:
* 1. Add a member to the Config struct.
- * 2. Add the option name to the "supported" Node in
- * get_supported_options.
- * 3. Initialise the new Config member in to_Config.
- * The functions set_from_yaml (for mandatory options) and
- * set_from_yaml_if_defined (non-mandatory) may be helpful.
- * 4. Add a new entry (with short description) to config.yaml
+ * 2. Inside "src/YAMLreader.cc":
+ * - Add the option name to the "supported" Node in
+ * get_supported_options.
+ * - Initialise the new Config member in to_Config.
+ * The functions set_from_yaml (for mandatory options) and
+ * set_from_yaml_if_defined (non-mandatory) may be helpful.
+ * 3. Add a new entry (with short description) to config.yaml
*/
struct Config {
ScaleGenerator scale_gen; /**< Scale */
JetParameters resummation_jets; /**< Resummation Jets */
JetParameters fixed_order_jets; /**< Fixed-Order Jets */
double min_extparton_pt; /**< Min External Parton Pt*/
double max_ext_soft_pt_fraction; /**< Min External Parton Pt Fraction */
int trials; /**< Number of resummation points to generate per FO */
- bool log_correction; /**< Log Correct On or Off */
+ //! Log Correct from running of \f$\alpha_s$\f On or Off
+ bool log_correction;
bool unweight; /**< Unweight On or Off */
- std::vector<OutputFile> output; /**< Output File Type */
+ std::vector<OutputFile> output; /**< Output Files Type */
optional<std::string> RanLux_init; /**< Ranlux File Choice*/
- EventTreatMap treat; /**< Event Treat Map? */
+ //! Map to decide what to do for differnt EventTypes
+ EventTreatMap treat;
YAML::Node analysis_parameters; /**< Analysis Parameters */
//! Settings for Effective Higgs-Gluon Coupling
HiggsCouplingSettings Higgs_coupling;
};
- class EventReweighterParameter{
- private:
- Config config;
+ class Parameters{
+ protected:
+ const Config & config;
public:
- EventReweighterParameter(const Config & conf):config{conf}{}
- EventReweighterParameter(
- const JetParameters & jet_param, /**< external Jet parameter*/
- const EventTreatMap & treat, /**< EventType treatment */
- const double extpartonptmin, /**< External Parton \f$p_T\f$ Minimum */
- const double max_ext_soft_pt_fraction, /**< External Parton \f$p_T\f$ Maximum */
- const bool log_corr, /**< Logarithmic correction On or Off */
- const HiggsCouplingSettings & higgs_coupling /**< Higgs Coupling */
- )
- {
- config.resummation_jets = jet_param;
- config.min_extparton_pt = extpartonptmin;
- config.max_ext_soft_pt_fraction = max_ext_soft_pt_fraction;
- config.log_correction = log_corr;
- config.treat = treat;
- config.Higgs_coupling = higgs_coupling;
- }
- ///@{
- /// @ name possible output functions
- JetParameters jet_param() const {return config.resummation_jets;}
- double jet_ptmin() const {return jet_param().min_pt;}
- fastjet::JetDefinition jet_def() const {return jet_param().def;}
+ explicit Parameters(const Config & conf): config(conf){}
+ // explicit Parameters(const Parameters & param):
+ // config(param.getConfig()){}
+ const Config & get_Config() const {return config;}
+ };
- double min_extparton_pt() const {return config.min_extparton_pt;}
- double max_ext_soft_pt_fraction() const {return config.max_ext_soft_pt_fraction;}
+ class PhaseSpacePointParameters: public Parameters {
+ public:
+ explicit PhaseSpacePointParameters(const Config & conf): Parameters(conf){}
+ ///@{
+ /// @name getter functions
+ const JetParameters & jet_parameters() const
+ {return config.resummation_jets;}
+ double jet_ptmin() const
+ {return jet_parameters().min_pt;}
+ const fastjet::JetDefinition & jet_def() const
+ {return jet_parameters().def;}
+ double jet_R() const
+ {return jet_def().R();}
+
+ double min_ext_pt() const
+ {return config.min_extparton_pt;}
+ double max_ext_soft_pt_fraction() const
+ {return config.max_ext_soft_pt_fraction;}
+ ///@}
+ };
- bool log_correction() const {return config.log_correction;}
- EventTreatMap treat() const {return config.treat;}
+ class MartixElementParameters: public Parameters {
+ public:
+ explicit MartixElementParameters(const Config & conf):
+ Parameters(conf){}
+ ///@{
+ /// @name getter functions
+ const JetParameters & jet_parameters() const
+ {return config.resummation_jets;}
+ double jet_ptmin() const
+ {return jet_parameters().min_pt;}
+ const fastjet::JetDefinition & jet_def() const
+ {return jet_parameters().def;}
+
+ bool log_corr() const
+ {return config.log_correction;}
+
+ const HiggsCouplingSettings & Hgg_setting() const
+ {return config.Higgs_coupling;}
+ ///@}
+ };
- HiggsCouplingSettings Higgs_coupling() const {return config.Higgs_coupling;}
+ class EventReweighterParameters: public Parameters {
+ public:
+ explicit EventReweighterParameters(const Config & conf):
+ Parameters(conf){}
+ ///@{
+ /// @name getter functions
+ const JetParameters & jet_parameters() const
+ {return config.resummation_jets;}
+ double jet_ptmin() const
+ {return jet_parameters().min_pt;}
+ const fastjet::JetDefinition & jet_def() const
+ {return jet_parameters().def;}
+
+ bool log_corr() const
+ {return config.log_correction;}
+ const EventTreatMap & treat() const
+ {return config.treat;}
+
+ const HiggsCouplingSettings & Higgs_coupling() const
+ {return config.Higgs_coupling;}
+ ///@}
};
} // namespace RHEJ
diff --git a/src/EventReweighter.cc b/src/EventReweighter.cc
index 880028e..b863942 100644
--- a/src/EventReweighter.cc
+++ b/src/EventReweighter.cc
@@ -1,320 +1,302 @@
#include "RHEJ/EventReweighter.hh"
#include <string>
#include <unordered_map>
#include "RHEJ/PhaseSpacePoint.hh"
#include "RHEJ/PDG_codes.hh"
#include "RHEJ/config.hh" // ScaleGenerator definition
#include "RHEJ/debug.hh"
namespace RHEJ{
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();
UnclusteredEvent to_UnclusteredEvent(PhaseSpacePoint const & psp){
UnclusteredEvent result;
result.incoming = psp.incoming();
std::sort(
begin(result.incoming), end(result.incoming),
[](Sparticle o1, Sparticle 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;
}
- } // anonymous namespace
+ } // namespace anonymous
EventReweighter::EventReweighter(
LHEF::HEPRUP const & heprup,
- fastjet::JetDefinition jet_def, double jetptmin,
- EventTreatMap treat,
- double extpartonptmin, double max_ext_soft_pt_fraction,
- bool log_corr,
- HiggsCouplingSettings Higgs_coupling
+ Config const & conf
):
EventReweighter{
RHEJ::Beam{
heprup.EBMUP.first,
{{
static_cast<RHEJ::ParticleID>(heprup.IDBMUP.first),
static_cast<RHEJ::ParticleID>(heprup.IDBMUP.second)
}}
},
heprup.PDFSUP.first,
- jet_def, jetptmin,
- std::move(treat),
- extpartonptmin, max_ext_soft_pt_fraction,
- log_corr,
- std::move(Higgs_coupling)
+ conf
}
{
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,
- fastjet::JetDefinition jet_def, double jetptmin,
- EventTreatMap treat,
- double extpartonptmin, double max_ext_soft_pt_fraction,
- bool log_corr,
- HiggsCouplingSettings Higgs_coupling
+ Config const & conf
):
- extpartonptmin_{extpartonptmin},
- max_ext_soft_pt_fraction_{max_ext_soft_pt_fraction},
- jetptmin_{jetptmin},
+ param(conf),
E_beam_{beam.E},
- jet_def_{jet_def},
pdf_{pdf_id, beam.type.front(), beam.type.back()},
MEt2_{
[this](double mu){ return pdf_.Halphas(mu); },
- jet_def, jetptmin,
- log_corr, std::move(Higgs_coupling)
- },
- treat_{std::move(treat)}
+ param.get_Config()
+ }
{}
PDF const & EventReweighter::pdf() const{
return pdf_;
}
namespace{
static_assert(
std::numeric_limits<double>::has_infinity, "infinity not supported"
);
// there is no simple way to create a vector of move-only objects
// this is a clumsy work-around
ScaleGenerator make_identity(){
- std::vector<std::unique_ptr<ScaleFunction>> scale_fun;
+ std::vector<std::shared_ptr<ScaleFunction>> scale_fun;
scale_fun.emplace_back(new InputScales);
return ScaleGenerator{
ScaleConfig{
std::move(scale_fun), {}, std::numeric_limits<double>::infinity()
}
};
}
const ScaleGenerator identity{make_identity()};
}
std::vector<Event> EventReweighter::reweight(
Event const & input_ev, int num_events
){
return reweight(input_ev, num_events, identity);
}
std::vector<Event> EventReweighter::reweight(
Event const & input_ev, int num_events,
ScaleGenerator const & gen_scales
){
auto res_events = gen_res_events(input_ev, num_events);
if(res_events.empty()) return {};
for(auto & event: res_events) event = gen_scales(event);
return rescale(input_ev, std::move(res_events));
}
/**
* \brief main generation/reweighting function: generate phase space points and divide out Born factors
*/
std::vector<Event> EventReweighter::gen_res_events(
Event const & ev,
int phase_space_points
){
assert(ev.variations().empty());
- switch(treat_.at(ev.type())){
+ 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,
- jet_def_, jetptmin_,
- extpartonptmin_, max_ext_soft_pt_fraction_
+ param.get_Config()
};
if(psp.weight() == 0.) continue;
if(psp.incoming()[0].E() > E_beam_ || psp.incoming()[1].E() > E_beam_) continue;
resummation_events.emplace_back(
- to_UnclusteredEvent(std::move(psp)), jet_def_, jetptmin_
+ to_UnclusteredEvent(std::move(psp)), param.jet_def(), param.jet_ptmin()
);
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, jet_def_};
- return cs.inclusive_jets(jetptmin_).size() == ev.jets().size();
+ fastjet::ClusterSequence cs{out_as_PseudoJet, param.jet_def()};
+ return cs.inclusive_jets(param.jet_ptmin()).size() == ev.jets().size();
}
EventReweighter::EventFactors
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_;
EventFactors 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 & param: ev.variations()){
const double muf = 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;
}
EventReweighter::EventFactors
EventReweighter::matrix_elements(Event const & ev) const{
- assert(treat_.count(ev.type()) > 0);
- if(treat_.find(ev.type())->second == EventTreatment::keep){
+ assert(param.treat().count(ev.type()) > 0);
+ if(param.treat().find(ev.type())->second == EventTreatment::keep){
return fixed_order_scale_ME(ev);
}
// precompute overall kinematic factor
const double ME_kin = MEt2_.tree_kin(ev.incoming(), ev.outgoing(), true);
EventFactors result;
std::unordered_map<double, double> known_ME;
result.central = MEt2_(
ev.central().mur,
ev.incoming(), ev.outgoing(),
true
);
known_ME.emplace(ev.central().mur, result.central);
result.variations.reserve(ev.variations().size());
for(auto const & param: ev.variations()){
const double mur = param.mur;
auto cur_ME = known_ME.find(mur);
if(cur_ME == known_ME.end()){
const double ME = MEt2_.tree_param(
mur, ev.incoming(), ev.outgoing()
)*ME_kin*MEt2_.virtual_corrections(
mur, ev.incoming(), ev.outgoing()
);
cur_ME = known_ME.emplace(mur, ME).first;
}
result.variations.emplace_back(cur_ME->second);
}
assert(result.variations.size() == ev.variations().size());
return result;
}
double EventReweighter::tree_matrix_element(Event const & ev) const{
assert(ev.variations().empty());
- assert(treat_.count(ev.type()) > 0);
- if(treat_.find(ev.type())->second == EventTreatment::keep){
+ 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().mur,
ev.incoming(), ev.outgoing(),
false
);
}
EventReweighter::EventFactors
EventReweighter::fixed_order_scale_ME(Event const & ev) const{
const int alpha_s_power = std::count_if(
begin(ev.outgoing()), end(ev.outgoing()),
[](Sparticle const & p){ return is_parton(p); }
);
EventFactors 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;
}
}
diff --git a/src/MatrixElement.cc b/src/MatrixElement.cc
index 58731ad..f5062a8 100644
--- a/src/MatrixElement.cc
+++ b/src/MatrixElement.cc
@@ -1,763 +1,758 @@
#include "RHEJ/MatrixElement.hh"
#include <CLHEP/Random/Randomize.h>
#include <CLHEP/Random/RanluxEngine.h>
#include "RHEJ/currents.hh"
#include "RHEJ/PDG_codes.hh"
#include "RHEJ/uno.hh"
#include "RHEJ/debug.hh"
namespace{
constexpr int N_C = 3;
constexpr int C_A = N_C;
constexpr double C_F = (N_C*N_C - 1.)/(2.*N_C);
constexpr double t_f = 1./2.;
constexpr double clambda = 0.2;
constexpr int n_f = 5;
constexpr double beta0 = 11./3.*C_A - 4./3.*t_f*n_f;
}
namespace RHEJ{
//cf. last line of eq. (22) in \ref Andersen:2011hs
double MatrixElement::omega0(
double alpha_s, double mur,
fastjet::PseudoJet const & q_j, double lambda
) const {
const double result = - alpha_s*N_C/M_PI*log(q_j.perp2()/(lambda*lambda));
- if(! log_corr_) return result;
+ if(! param.log_corr()) return result;
// use alpha_s(sqrt(q_j*lambda)), evolved to mur
return (
1. + alpha_s/(4.*M_PI)*beta0*log(mur*mur/(q_j.perp()*lambda))
)*result;
}
double MatrixElement::virtual_corrections(
double mur,
std::array<Sparticle, 2> const & in,
std::vector<Sparticle> const & out
) const{
fastjet::PseudoJet const & pa = in.front().p;
#ifndef NDEBUG
fastjet::PseudoJet const & pb = in.back().p;
#endif
assert(std::is_sorted(out.begin(), out.end(), rapidity_less{}));
assert(out.size() >= 2);
assert(pa.pz() < pb.pz());
fastjet::PseudoJet q = pa - out[0].p;
size_t first_idx = 0;
size_t last_idx = out.size() - 1;
// if there is a Higgs or unordered gluon outside the extremal partons
// then it is not part of the FKL ladder and does not contribute
// to the virtual corrections
if(out.front().type == pid::Higgs || has_unob_gluon(in, out)){
q -= out[1].p;
++first_idx;
}
if(out.back().type == pid::Higgs || has_unof_gluon(in, out)){
--last_idx;
}
double exponent = 0;
const double alpha_s = alpha_s_(mur);
for(size_t j = first_idx; j < last_idx; ++j){
exponent += omega0(alpha_s, mur, q, clambda)*(
out[j+1].rapidity() - out[j].rapidity()
);
q -= out[j+1].p;
}
assert(
nearby(q, -1*pb)
|| out.back().type == pid::Higgs
|| has_unof_gluon(in, out)
);
return exp(exponent);
}
}
namespace {
//! Lipatov vertex for partons emitted into extremal jets
double C2Lipatov(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2)
{
CLHEP::HepLorentzVector temptrans=-(qav+qbv);
CLHEP::HepLorentzVector p5=qav-qbv;
CLHEP::HepLorentzVector CL=temptrans+(qav.m2()/p5.dot(p1)+2.*p5.dot(p2)/p1.dot(p2))*p1-p2*(qbv.m2()/p5.dot(p2)+2.*p5.dot(p1)/p1.dot(p2));
#if printoutput
cout << "#Fadin qa : "<<qav<<endl;
cout << "#Fadin qb : "<<qbv<<endl;
cout << "#Fadin p1 : "<<p1<<endl;
cout << "#Fadin p2 : "<<p2<<endl;
cout << "#Fadin p5 : "<<p5<<endl;
cout << "#Fadin Gauge Check : "<< CL.dot(p5)<<endl;
cout << "#Fadin C2L : "<< -CL.dot(CL)<<" "<<-CL.dot(CL)/(qav.m2()*qbv.m2())/(4./p5.perp2())<<endl;
#endif
#if 0
if (-CL.dot(CL)<0.)
// if (fabs(CL.dot(p5))>fabs(CL.dot(CL))) // not sufficient!
return 0.;
else
#endif
return -CL.dot(CL);
}
//! Lipatov vertex with soft subtraction for partons emitted into extremal jets
double C2Lipatovots(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2)
{
double kperp=(qav-qbv).perp();
if (kperp>clambda)
return C2Lipatov(qav, qbv, p1, p2)/(qav.m2()*qbv.m2());
else {
double Cls=(C2Lipatov(qav, qbv, p1, p2)/(qav.m2()*qbv.m2()));
double temp=Cls-4./(kperp*kperp);
// std::cout <<kperp <<" "<<temp<<" "<<4./(kperp*kperp)<<" "<<(C2Lipatov(qav, qbv, pa, pb, p1, p2)/(qav.m2()*qbv.m2()))<<std::endl;
return temp;
}
}
//! Lipatov vertex
double C2Lipatov(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv, CLHEP::HepLorentzVector pim, CLHEP::HepLorentzVector pip,CLHEP::HepLorentzVector pom, CLHEP::HepLorentzVector pop) // B
{
CLHEP::HepLorentzVector temptrans=-(qav+qbv);
CLHEP::HepLorentzVector p5=qav-qbv;
CLHEP::HepLorentzVector CL=temptrans+qav.m2()*(1./p5.dot(pip)*pip+1./p5.dot(pop)*pop)/2.-qbv.m2()*(1./p5.dot(pim)*pim+1./p5.dot(pom)*pom)/2.+(pip*(p5.dot(pim)/pip.dot(pim)+p5.dot(pom)/pip.dot(pom)) + pop*(p5.dot(pim)/pop.dot(pim)+p5.dot(pom)/pop.dot(pom)) - pim*(p5.dot(pip)/pip.dot(pim) + p5.dot(pop)/pop.dot(pim)) - pom*(p5.dot(pip)/pip.dot(pom) + p5.dot(pop)/pop.dot(pom)) )/2.;
return -CL.dot(CL);
}
//! Lipatov vertex with soft subtraction
double C2Lipatovots(CLHEP::HepLorentzVector qav, CLHEP::HepLorentzVector qbv, CLHEP::HepLorentzVector pa, CLHEP::HepLorentzVector pb, CLHEP::HepLorentzVector p1, CLHEP::HepLorentzVector p2)
{
double kperp=(qav-qbv).perp();
if (kperp>clambda)
return C2Lipatov(qav, qbv, pa, pb, p1, p2)/(qav.m2()*qbv.m2());
else {
double Cls=(C2Lipatov(qav, qbv, pa, pb, p1, p2)/(qav.m2()*qbv.m2()));
double temp=Cls-4./(kperp*kperp);
return temp;
}
}
/** Matrix element squared for tree-level current-current scattering
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @returns ME Squared for Tree-Level Current-Current Scattering
*/
double ME_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa
){
if (aptype==21&&bptype==21) {
return jM2gg(pn,pb,p1,pa);
} else if (aptype==21&&bptype!=21) {
if (bptype > 0)
return jM2qg(pn,pb,p1,pa);
else
return jM2qbarg(pn,pb,p1,pa);
}
else if (bptype==21&&aptype!=21) { // ----- || -----
if (aptype > 0)
return jM2qg(p1,pa,pn,pb);
else
return jM2qbarg(p1,pa,pn,pb);
}
else { // they are both quark
if (bptype>0) {
if (aptype>0)
return jM2qQ(pn,pb,p1,pa);
else
return jM2qQbar(pn,pb,p1,pa);
}
else {
if (aptype>0)
return jM2qQbar(p1,pa,pn,pb);
else
return jM2qbarQbar(pn,pb,p1,pa);
}
}
throw std::logic_error("unknown particle types");
}
/** \brief Matrix element squared for tree-level current-current scattering with Higgs
* @param aptype Particle a PDG ID
* @param bptype Particle b PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param qH t-channel momentum before Higgs
* @param qHp1 t-channel momentum after Higgs
* @returns ME Squared for Tree-Level Current-Current Scattering with Higgs
*/
double ME_Higgs_current(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & qH, // t-channel momentum before Higgs
CLHEP::HepLorentzVector const & qHp1, // t-channel momentum after Higgs
double mt, bool include_bottom, double mb
){
if (aptype==21&&bptype==21) // gg initial state
return MH2gg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else if (aptype==21&&bptype!=21) {
if (bptype > 0)
return MH2qg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4./9.;
else
return MH2qbarg(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4./9.;
}
else if (bptype==21&&aptype!=21) {
if (aptype > 0)
return MH2qg(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb)*4./9.;
else
return MH2qbarg(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb)*4./9.;
}
else { // they are both quark
if (bptype>0) {
if (aptype>0)
return MH2qQ(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4.*4./(9.*9.);
else
return MH2qQbar(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4.*4./(9.*9.);
}
else {
if (aptype>0)
return MH2qQbar(p1,pa,pn,pb,-qH,-qHp1,mt,include_bottom,mb)*4.*4./(9.*9.);
else
return MH2qbarQbar(pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb)*4.*4./(9.*9.);
}
}
throw std::logic_error("unknown particle types");
}
/** \brief Current matrix element squared with Higgs and unordered forward emission
* @param aptype Particle A PDG ID
* @param bptype Particle B PDG ID
* @param punof Unordered Particle Momentum
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param qH t-channel momentum before Higgs
* @param qHp1 t-channel momentum after Higgs
* @returns ME Squared with Higgs and unordered forward emission
*/
double ME_Higgs_current_unof(
int aptype, int bptype,
CLHEP::HepLorentzVector const & punof,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & qH, // t-channel momentum before Higgs
CLHEP::HepLorentzVector const & qHp1, // t-channel momentum after Higgs
double mt, bool include_bottom, double mb
){
if (aptype==21&&bptype!=21) {
if (bptype > 0)
return jM2unogqHg(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unogqbarHg(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else { // they are both quark
if (bptype>0) {
if (aptype>0)
return jM2unogqHQ(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unogqHQbar(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else {
if (aptype>0)
return jM2unogqbarHQ(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unogqbarHQbar(punof,pn,pb,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
}
throw std::logic_error("unknown particle types");
}
/** \brief Current matrix element squared with Higgs and unordered backward emission
* @param aptype Particle A PDG ID
* @param bptype Particle B PDG ID
* @param pn Particle n Momentum
* @param pb Particle b Momentum
* @param punob Unordered back Particle Momentum
* @param p1 Particle 1 Momentum
* @param pa Particle a Momentum
* @param qH t-channel momentum before Higgs
* @param qHp1 t-channel momentum after Higgs
* @returns ME Squared with Higgs and unordered backward emission
*/
double ME_Higgs_current_unob(
int aptype, int bptype,
CLHEP::HepLorentzVector const & pn,
CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & punob,
CLHEP::HepLorentzVector const & p1,
CLHEP::HepLorentzVector const & pa,
CLHEP::HepLorentzVector const & qH, // t-channel momentum before Higgs
CLHEP::HepLorentzVector const & qHp1, // t-channel momentum after Higgs
double mt, bool include_bottom, double mb
){
if (bptype==21&&aptype!=21) {
if (aptype > 0)
return jM2unobgHQg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unobgHQbarg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else { // they are both quark
if (aptype>0) {
if (bptype>0)
return jM2unobqHQg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unobqbarHQg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
else {
if (bptype>0)
return jM2unobqHQbarg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
else
return jM2unobqbarHQbarg(pn,pb,punob,p1,pa,-qHp1,-qH,mt,include_bottom,mb);
}
}
throw std::logic_error("unknown particle types");
}
CLHEP::HepLorentzVector to_HepLorentzVector(RHEJ::Sparticle const & particle){
return {particle.p.px(), particle.p.py(), particle.p.pz(), particle.p.E()};
}
-} // RHEJ namespace
+} // namespace RHEJ
namespace RHEJ{
MatrixElement::MatrixElement(
std::function<double (double)> alpha_s,
- fastjet::JetDefinition jet_def, double jetptmin,
- bool log_corr,
- HiggsCouplingSettings Hgg_settings
+ Config const & conf
):
alpha_s_{std::move(alpha_s)},
- Hgg_settings_{Hgg_settings},
- jet_def_{jet_def},
- jetptmin_{jetptmin},
- log_corr_{log_corr}
+ param(conf)
{}
double MatrixElement::operator()(
double mur,
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const {
return tree(
mur,
incoming, outgoing,
check_momenta
)*virtual_corrections(
mur,
incoming, outgoing
);
}
double MatrixElement::tree_kin(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const {
assert(
std::is_sorted(
incoming.begin(), incoming.end(),
[](Sparticle o1, Sparticle o2){return o1.p.pz()<o2.p.pz();}
)
);
assert(std::is_sorted(outgoing.begin(), outgoing.end(), rapidity_less{}));
auto AWZH_boson = std::find_if(
begin(outgoing), end(outgoing),
[](Sparticle const & p){return is_AWZH_boson(p);}
);
if(AWZH_boson == end(outgoing)){
return tree_kin_jets(incoming, outgoing, check_momenta);
}
switch(AWZH_boson->type){
case pid::Higgs: {
static constexpr double mH = 125.;
const double alpha_s_mH = alpha_s_(mH);
return alpha_s_mH*alpha_s_mH/(256.*pow(M_PI, 5))*tree_kin_Higgs(
incoming, outgoing, check_momenta
);
}
// TODO
case pid::Wp:
case pid::Wm:
case pid::photon:
case pid::Z:
default:
throw std::logic_error("Emission of boson of unsupported type");
}
}
namespace{
constexpr int extremal_jet_idx = 1;
constexpr int no_extremal_jet_idx = 0;
bool treat_as_extremal(Sparticle const & parton){
return parton.p.user_index() == extremal_jet_idx;
}
template<class InputIterator>
double FKL_ladder_weight(
InputIterator begin_gluon, InputIterator end_gluon,
CLHEP::HepLorentzVector const & q0,
CLHEP::HepLorentzVector const & pa, CLHEP::HepLorentzVector const & pb,
CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & pn
){
double wt = 1;
auto qi = q0;
for(auto gluon_it = begin_gluon; gluon_it != end_gluon; ++gluon_it){
assert(gluon_it->type == pid::gluon);
const auto g = to_HepLorentzVector(*gluon_it);
const auto qip1 = qi - g;
if(treat_as_extremal(*gluon_it)){
wt *= C2Lipatovots(qip1, qi, pa, pb)*C_A;
} else{
wt *= C2Lipatovots(qip1, qi, pa, pb, p1, pn)*C_A;
}
qi = qip1;
}
return wt;
}
- } // anonymous namespace
+ } // namespace anonymous
std::vector<Sparticle> MatrixElement::tag_extremal_jet_partons(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> out_partons, bool check_momenta
) const{
if(!check_momenta){
for(auto & parton: out_partons){
parton.p.set_user_index(no_extremal_jet_idx);
}
return out_partons;
}
- fastjet::ClusterSequence cs(to_PseudoJet(out_partons), jet_def_);
- const auto jets = sorted_by_rapidity(cs.inclusive_jets(jetptmin_));
+ fastjet::ClusterSequence cs(to_PseudoJet(out_partons), param.jet_def());
+ const auto jets = sorted_by_rapidity(cs.inclusive_jets(param.jet_ptmin()));
assert(jets.size() >= 2);
auto most_backward = begin(jets);
auto most_forward = end(jets) - 1;
// skip jets caused by unordered emission
if(has_unob_gluon(incoming, out_partons)){
assert(jets.size() >= 3);
++most_backward;
}
else if(has_unof_gluon(incoming, out_partons)){
assert(jets.size() >= 3);
--most_forward;
}
const auto extremal_jet_indices = cs.particle_jet_indices(
{*most_backward, *most_forward}
);
assert(extremal_jet_indices.size() == out_partons.size());
for(size_t i = 0; i < out_partons.size(); ++i){
assert(RHEJ::is_parton(out_partons[i]));
const int idx = (extremal_jet_indices[i]>=0)?
extremal_jet_idx:
no_extremal_jet_idx;
out_partons[i].p.set_user_index(idx);
}
return out_partons;
}
double MatrixElement::tree_kin_jets(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> partons,
bool check_momenta
) const {
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
if(has_unob_gluon(incoming, partons) || has_unof_gluon(incoming, partons)){
throw std::logic_error("unordered emission not implemented for pure jets");
}
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
const auto p1 = to_HepLorentzVector(partons.front());
const auto pn = to_HepLorentzVector(partons.back());
return ME_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa
)/(4*(N_C*N_C - 1))*FKL_ladder_weight(
begin(partons) + 1, end(partons) - 1,
pa - p1, pa, pb, p1, pn
);
}
double MatrixElement::tree_kin_Higgs(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const {
if(has_uno_gluon(incoming, outgoing)){
return tree_kin_Higgs_between(incoming, outgoing, check_momenta);
}
if(outgoing.front().type == pid::Higgs){
return tree_kin_Higgs_first(incoming, outgoing, check_momenta);
}
if(outgoing.back().type == pid::Higgs){
return tree_kin_Higgs_last(incoming, outgoing, check_momenta);
}
return tree_kin_Higgs_between(incoming, outgoing, check_momenta);
}
double MatrixElement::MH2_forwardH(
RHEJ::ParticleID id,
CLHEP::HepLorentzVector p1out, CLHEP::HepLorentzVector p1in,
CLHEP::HepLorentzVector p2out, CLHEP::HepLorentzVector p2in,
CLHEP::HepLorentzVector pH,
double t1, double t2
) const{
ignore(p2out, p2in);
const double shat = p1in.invariantMass2(p2in);
assert(RHEJ::is_parton(id));
if(id != RHEJ::pid::gluon){
return 9./2.*shat*shat*C2qHqm(p1in,p1out,pH)/(t1*t2);
}
// gluon case
#ifdef RHEJ_BUILD_WITH_QCDLOOP
- if(!Hgg_settings_.use_impact_factors){
+ if(!param.Hgg_setting().use_impact_factors){
return C_A/C_F*1./(16*M_PI*M_PI)*t1/t2*MH2gq_outsideH(
p1out, p1in, p2out, p2in, pH,
- Hgg_settings_.mt, Hgg_settings_.include_bottom,
- Hgg_settings_.mb
+ param.Hgg_setting().mt, param.Hgg_setting().include_bottom,
+ param.Hgg_setting().mb
);
}
#endif
return 9./2.*shat*shat*(
C2gHgp(p1in,p1out,pH) + C2gHgm(p1in,p1out,pH)
)/(t1*t2);
}
double MatrixElement::tree_kin_Higgs_first(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const {
assert(outgoing.front().type == pid::Higgs);
const auto pH = to_HepLorentzVector(outgoing.front());
const auto partons = tag_extremal_jet_partons(
incoming,
std::vector<Sparticle>(begin(outgoing) + 1, end(outgoing)),
check_momenta
);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
const auto p1 = to_HepLorentzVector(partons.front());
const auto pn = to_HepLorentzVector(partons.back());
const auto q0 = pa - p1 - pH;
const double t1 = q0.m2();
const double t2 = (pn - pb).m2();
double wt = MH2_forwardH(
incoming[0].type, p1, pa, pn, pb, pH,
t1, t2
)*FKL_ladder_weight(
begin(partons) + 1, end(partons) - 1,
q0, pa, pb, p1, pn
);
for(auto const & inc: incoming){
if(inc.type != pid::gluon) wt *= C_F/C_A;
}
return wt;
}
double MatrixElement::tree_kin_Higgs_last(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const {
assert(outgoing.back().type == pid::Higgs);
const auto pH = to_HepLorentzVector(outgoing.back());
const auto partons = tag_extremal_jet_partons(
incoming,
std::vector<Sparticle>(begin(outgoing), end(outgoing) - 1),
check_momenta
);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto p1 = to_HepLorentzVector(partons.front());
const auto pn = to_HepLorentzVector(partons.back());
auto q0 = pa - p1;
const double t1 = q0.m2();
const double t2 = (pn + pH - pb).m2();
double wt = MH2_forwardH(
incoming[1].type, pn, pb, p1, pa, pH,
t2, t1
)*FKL_ladder_weight(
begin(partons) + 1, end(partons) - 1,
q0, pa, pb, p1, pn
);
for(auto const & inc: incoming){
if(inc.type != pid::gluon) wt *= C_F/C_A;
}
return wt;
}
double MatrixElement::tree_kin_Higgs_between(
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const {
const auto the_Higgs = std::find_if(
begin(outgoing), end(outgoing),
[](Sparticle const & s){ return s.type == pid::Higgs; }
);
assert(the_Higgs != end(outgoing));
const auto pH = to_HepLorentzVector(*the_Higgs);
std::vector<Sparticle> partons(begin(outgoing), the_Higgs);
partons.insert(end(partons), the_Higgs + 1, end(outgoing));
partons = tag_extremal_jet_partons(incoming, partons, check_momenta);
const auto pa = to_HepLorentzVector(incoming[0]);
const auto pb = to_HepLorentzVector(incoming[1]);
auto p1 = to_HepLorentzVector(
partons[has_unob_gluon(incoming, outgoing)?1:0]
);
auto pn = to_HepLorentzVector(
partons[partons.size() - (has_unof_gluon(incoming, outgoing)?2:1)]
);
auto first_after_Higgs = begin(partons) + (the_Higgs-begin(outgoing));
assert(
(first_after_Higgs == end(partons) && has_unob_gluon(incoming, outgoing))
|| first_after_Higgs->rapidity() >= the_Higgs->rapidity()
);
assert(
(first_after_Higgs == begin(partons) && has_unof_gluon(incoming, outgoing))
|| (first_after_Higgs-1)->rapidity() <= the_Higgs->rapidity()
);
// always treat the Higgs as if it were in between the extremal FKL partons
if(first_after_Higgs == begin(partons)) ++first_after_Higgs;
else if(first_after_Higgs == end(partons)) --first_after_Higgs;
// t-channel momentum before Higgs
auto qH = pa;
for(auto parton_it = begin(partons); parton_it != first_after_Higgs; ++parton_it){
qH -= to_HepLorentzVector(*parton_it);
}
auto q0 = pa - p1;
auto begin_ladder = begin(partons) + 1;
auto end_ladder = end(partons) - 1;
double current_factor;
if(has_unob_gluon(incoming, outgoing)){
current_factor = 9./2.*ME_Higgs_current_unob(
incoming[0].type, incoming[1].type,
pn, pb, to_HepLorentzVector(partons.front()), p1, pa, qH, qH - pH,
- Hgg_settings_.mt, Hgg_settings_.include_bottom, Hgg_settings_.mb
+ param.Hgg_setting().mt, param.Hgg_setting().include_bottom, param.Hgg_setting().mb
);
const auto p_unob = to_HepLorentzVector(partons.front());
q0 -= p_unob;
p1 += p_unob;
++begin_ladder;
}
else if(has_unof_gluon(incoming, outgoing)){
current_factor = 9./2.*ME_Higgs_current_unof(
incoming[0].type, incoming[1].type,
to_HepLorentzVector(partons.back()), pn, pb, p1, pa, qH, qH - pH,
- Hgg_settings_.mt, Hgg_settings_.include_bottom, Hgg_settings_.mb
+ param.Hgg_setting().mt, param.Hgg_setting().include_bottom, param.Hgg_setting().mb
);
pn += to_HepLorentzVector(partons.back());
--end_ladder;
}
else{
current_factor = ME_Higgs_current(
incoming[0].type, incoming[1].type,
pn, pb, p1, pa, qH, qH - pH,
- Hgg_settings_.mt, Hgg_settings_.include_bottom, Hgg_settings_.mb
+ param.Hgg_setting().mt, param.Hgg_setting().include_bottom, param.Hgg_setting().mb
);
}
const double ladder_factor = FKL_ladder_weight(
begin_ladder, first_after_Higgs,
q0, pa, pb, p1, pn
)*FKL_ladder_weight(
first_after_Higgs, end_ladder,
qH - pH, pa, pb, p1, pn
);
return current_factor*9./8.*ladder_factor;
}
double MatrixElement::tree_param_partons(
double alpha_s, double mur,
std::vector<Sparticle> const & partons
) const{
const double gs2 = 4.*M_PI*alpha_s;
double wt = std::pow(gs2, partons.size());
- if(log_corr_){
+ if(param.log_corr()){
// use alpha_s(q_perp), evolved to mur
assert(partons.size() >= 2);
for(size_t i = 1; i < partons.size()-1; ++i){
wt *= 1 + alpha_s/(2*M_PI)*beta0*log(mur/partons[i].p.perp());
}
}
return wt;
}
double MatrixElement::tree_param(
double mur,
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing
) const{
const double alpha_s = alpha_s_(mur);
if(has_unob_gluon(incoming, outgoing)){
return 4*M_PI*alpha_s*tree_param_partons(
alpha_s, mur, filter_partons({begin(outgoing) + 1, end(outgoing)})
);
}
if(has_unof_gluon(incoming, outgoing)){
return 4*M_PI*alpha_s*tree_param_partons(
alpha_s, mur, filter_partons({begin(outgoing), end(outgoing) - 1})
);
}
return tree_param_partons(alpha_s, mur, filter_partons(outgoing));
}
double MatrixElement::tree(
double mur,
std::array<Sparticle, 2> const & incoming,
std::vector<Sparticle> const & outgoing,
bool check_momenta
) const {
return tree_param(mur, incoming, outgoing)*tree_kin(
incoming, outgoing, check_momenta
);
}
} // namespace RHEJ
diff --git a/src/PhaseSpacePoint.cc b/src/PhaseSpacePoint.cc
index dc5fdc7..2be3323 100644
--- a/src/PhaseSpacePoint.cc
+++ b/src/PhaseSpacePoint.cc
@@ -1,587 +1,580 @@
#include "RHEJ/PhaseSpacePoint.hh"
#include <random>
#include "RHEJ/resummation_jet_momenta.hh"
#include "RHEJ/Jacobian.hh"
#include "RHEJ/RNGWrapper.hh"
#include "RHEJ/uno.hh"
#include "RHEJ/debug.hh"
#include "RHEJ/kinematics.hh"
namespace RHEJ{
namespace{
//generate Ranlux64Engine with fixed, predefined state
/*
* some (all?) of the Ranlux64Engine constructors leave fields
* uninitialised, invoking undefined behaviour. This can be
* circumvented by restoring the state from a file
*/
CLHEP::Ranlux64Engine gen_Ranlux64Engine(){
static const std::string state =
"9876\n"
"0.91280703978419097666\n"
"0.41606065829518357191\n"
"0.99156342622341142601\n"
"0.030922955274050423213\n"
"0.16206278421638486975\n"
"0.76151768001958330956\n"
"0.43765760066092695979\n"
"0.42904698253748563275\n"
"0.11476317525663759511\n"
"0.026620053590963976831\n"
"0.65953715764414511114\n"
"0.30136722624439826745\n"
"3.5527136788005009294e-15 4\n"
"1 202\n";
const std::string file = std::tmpnam(nullptr);
{
std::ofstream out{file};
out << state;
}
CLHEP::Ranlux64Engine result;
result.restoreStatus(file.c_str());
return result;
}
}
CLHEP::Ranlux64Engine PhaseSpacePoint::ran_{gen_Ranlux64Engine()};
void PhaseSpacePoint::reset_ranlux(std::string const & init_file){
reset_ranlux(init_file.c_str());
}
void PhaseSpacePoint::reset_ranlux(char const * init_file){
ran_.restoreStatus(init_file);
}
namespace {
constexpr int max_jet_user_idx = PhaseSpacePoint::ng_max;
bool is_nonjet_parton(fastjet::PseudoJet const & parton){
assert(parton.user_index() != -1);
return parton.user_index() > max_jet_user_idx;
}
bool is_jet_parton(fastjet::PseudoJet const & parton){
assert(parton.user_index() != -1);
return parton.user_index() <= max_jet_user_idx;
}
// user indices for partons with extremal rapidity
constexpr int unob_idx = -5;
constexpr int unof_idx = -4;
constexpr int backward_FKL_idx = -3;
constexpr int forward_FKL_idx = -2;
}
namespace{
double estimate_ng_mean(std::vector<fastjet::PseudoJet> const & Born_jets){
const double delta_y =
Born_jets.back().rapidity() - Born_jets.front().rapidity();
assert(delta_y > 0);
// Formula derived from fit in reversed HEJ intro paper
return 0.975052*delta_y;
}
}
std::vector<fastjet::PseudoJet> PhaseSpacePoint::cluster_jets(
std::vector<fastjet::PseudoJet> const & partons
) const{
- fastjet::ClusterSequence cs(partons, jet_def_);
- return cs.inclusive_jets(jetptmin_);
+ fastjet::ClusterSequence cs(partons, param.jet_def());
+ return cs.inclusive_jets(param.jet_ptmin());
}
bool PhaseSpacePoint::pass_resummation_cuts(
std::vector<fastjet::PseudoJet> const & jets
) const{
return cluster_jets(jets).size() == jets.size();
}
int PhaseSpacePoint::sample_ng(std::vector<fastjet::PseudoJet> const & Born_jets){
const double ng_mean = estimate_ng_mean(Born_jets);
std::poisson_distribution<int> dist(ng_mean);
RNGWrapper<CLHEP::Ranlux64Engine> rng{ran_};
const int ng = dist(rng);
assert(ng >= 0);
assert(ng < ng_max);
weight_ *= std::tgamma(ng + 1)*std::exp(ng_mean)*std::pow(ng_mean, -ng);
return ng;
}
void PhaseSpacePoint::copy_AWZH_boson_from(Event const & event){
auto const & from = event.outgoing();
const auto AWZH_boson = std::find_if(
begin(from), end(from),
[](Sparticle const & p){ return is_AWZH_boson(p); }
);
if(AWZH_boson == end(from)) return;
auto insertion_point = std::lower_bound(
begin(outgoing_), end(outgoing_), *AWZH_boson, rapidity_less{}
);
outgoing_.insert(insertion_point, *AWZH_boson);
// copy decay products
const int idx = std::distance(begin(from), AWZH_boson);
const auto decay_it = event.decays().find(idx);
if(decay_it != end(event.decays())){
const int new_idx = std::distance(begin(outgoing_), insertion_point);
assert(outgoing_[new_idx].type == AWZH_boson->type);
decays_.emplace(new_idx, decay_it->second);
}
assert(std::is_sorted(begin(outgoing_), end(outgoing_), rapidity_less{}));
}
- PhaseSpacePoint::PhaseSpacePoint(
- Event const & ev,
- fastjet::JetDefinition jet_def, double jetptmin,
- double extpartonptmin, double max_ext_soft_pt_fraction
- ):
+ PhaseSpacePoint::PhaseSpacePoint(Event const & ev, Config const & conf):
unob_{has_unob_gluon(ev.incoming(), ev.outgoing())},
unof_{!unob_ && has_unof_gluon(ev.incoming(), ev.outgoing())},
- extpartonptmin_{extpartonptmin},
- max_ext_soft_pt_fraction_{max_ext_soft_pt_fraction},
- jetptmin_{jetptmin},
- jet_def_{jet_def},
- splitter_{jet_def.R(), jet_def, jetptmin, ran_}
- {
- weight_ = 1;
- const auto Born_jets = sorted_by_rapidity(ev.jets());
- const int ng = sample_ng(Born_jets);
- weight_ /= std::tgamma(ng + 1);
- const int ng_jets = sample_ng_jets(ng, Born_jets);
- std::vector<fastjet::PseudoJet> out_partons = gen_non_jet(
- ng - ng_jets, ccut, jetptmin_
- );
- {
- const auto qperp = std::accumulate(
- begin(out_partons), end(out_partons),
- fastjet::PseudoJet{}
- );
- const auto jets = reshuffle(Born_jets, qperp);
- if(weight_ == 0.) return;
- if(! pass_resummation_cuts(jets)){
- weight_ = 0.;
- return;
- }
- std::vector<fastjet::PseudoJet> jet_partons = split(jets, ng_jets);
- if(weight_ == 0.) return;
- rescale_rapidities(
- out_partons,
- most_backward_FKL(jet_partons).rapidity(),
- most_forward_FKL(jet_partons).rapidity()
- );
- if(! cluster_jets(out_partons).empty()){
+ param(conf),
+ splitter_{param.jet_R(), param.jet_def(), param.jet_ptmin(), ran_}
+ {
+ weight_ = 1;
+ const auto Born_jets = sorted_by_rapidity(ev.jets());
+ const int ng = sample_ng(Born_jets);
+ weight_ /= std::tgamma(ng + 1);
+ const int ng_jets = sample_ng_jets(ng, Born_jets);
+ std::vector<fastjet::PseudoJet> out_partons = gen_non_jet(
+ ng - ng_jets, ccut, param.jet_ptmin()
+ );
+ {
+ const auto qperp = std::accumulate(
+ begin(out_partons), end(out_partons),
+ fastjet::PseudoJet{}
+ );
+ const auto jets = reshuffle(Born_jets, qperp);
+ if(weight_ == 0.) return;
+ if(! pass_resummation_cuts(jets)){
weight_ = 0.;
return;
- }
- std::sort(begin(out_partons), end(out_partons), rapidity_less{});
- assert(
- std::is_sorted(begin(jet_partons), end(jet_partons), rapidity_less{})
- );
- const auto first_jet_parton = out_partons.insert(
- end(out_partons), begin(jet_partons), end(jet_partons)
- );
- std::inplace_merge(
- begin(out_partons), first_jet_parton, end(out_partons), rapidity_less{}
- );
- }
- if(! jets_ok(Born_jets, out_partons)){
- weight_ = 0.;
- return;
- }
- weight_ *= phase_space_normalisation(Born_jets.size(), out_partons.size());
-
- outgoing_.reserve(out_partons.size() + 1); // one slot for possible A, W, Z, H
- for(auto & p: out_partons){
- outgoing_.emplace_back(Sparticle{pid::gluon, std::move(p)});
- }
- most_backward_FKL(outgoing_).type = ev.incoming().front().type;
- most_forward_FKL(outgoing_).type = ev.incoming().back().type;
- copy_AWZH_boson_from(ev);
-
- assert(!outgoing_.empty());
- reconstruct_incoming(ev.incoming());
- }
+ }
+ std::vector<fastjet::PseudoJet> jet_partons = split(jets, ng_jets);
+ if(weight_ == 0.) return;
+ rescale_rapidities(
+ out_partons,
+ most_backward_FKL(jet_partons).rapidity(),
+ most_forward_FKL(jet_partons).rapidity()
+ );
+ if(! cluster_jets(out_partons).empty()){
+ weight_ = 0.;
+ return;
+ }
+ std::sort(begin(out_partons), end(out_partons), rapidity_less{});
+ assert(
+ std::is_sorted(begin(jet_partons), end(jet_partons), rapidity_less{})
+ );
+ const auto first_jet_parton = out_partons.insert(
+ end(out_partons), begin(jet_partons), end(jet_partons)
+ );
+ std::inplace_merge(
+ begin(out_partons), first_jet_parton, end(out_partons), rapidity_less{}
+ );
+ }
+ if(! jets_ok(Born_jets, out_partons)){
+ weight_ = 0.;
+ return;
+ }
+ weight_ *= phase_space_normalisation(Born_jets.size(), out_partons.size());
+
+ outgoing_.reserve(out_partons.size() + 1); // one slot for possible A, W, Z, H
+ for(auto & p: out_partons){
+ outgoing_.emplace_back(Sparticle{pid::gluon, std::move(p)});
+ }
+ most_backward_FKL(outgoing_).type = ev.incoming().front().type;
+ most_forward_FKL(outgoing_).type = ev.incoming().back().type;
+ copy_AWZH_boson_from(ev);
+
+ assert(!outgoing_.empty());
+ reconstruct_incoming(ev.incoming());
+ }
std::vector<fastjet::PseudoJet> PhaseSpacePoint::gen_non_jet(
int count, double ptmin, double ptmax
){
// heuristic parameters for pt sampling
const double ptpar = 1.3 + count/5.;
const double temp1 = atan((ptmax - ptmin)/ptpar);
std::vector<fastjet::PseudoJet> partons(count);
for(size_t i = 0; i < (size_t) count; ++i){
const double r1 = ran_.flat();
const double pt = ptmin + ptpar*tan(r1*temp1);
const double temp2 = cos(r1*temp1);
const double phi = 2*M_PI*ran_.flat();
weight_ *= 2.0*M_PI*pt*ptpar*temp1/(temp2*temp2);
// we don't know the allowed rapidity span yet,
// set a random value to be rescaled later on
const double y = ran_.flat();
partons[i].reset_PtYPhiM(pt, y, phi);
// Set user index higher than any jet-parton index
// in order to assert that these are not inside jets
partons[i].set_user_index(i + 1 + RHEJ::PhaseSpacePoint::ng_max);
assert(ptmin-1e-5 <= partons[i].pt() && partons[i].pt() <= ptmax+1e-5);
}
assert(std::all_of(partons.cbegin(), partons.cend(), is_nonjet_parton));
return partons;
}
void PhaseSpacePoint::rescale_rapidities(
std::vector<fastjet::PseudoJet> & partons,
double ymin, double ymax
){
constexpr double ep = 1e-7;
for(auto & parton: partons){
assert(0 <= parton.rapidity() && parton.rapidity() <= 1);
const double dy = ymax - ymin - 2*ep;
const double y = ymin + ep + dy*parton.rapidity();
parton.reset_momentum_PtYPhiM(parton.pt(), y, parton.phi());
weight_ *= dy;
assert(ymin <= parton.rapidity() && parton.rapidity() <= ymax);
}
}
namespace {
template<typename T, typename... Rest>
auto min(T const & a, T const & b, Rest&&... r) {
using std::min;
return min(a, min(b, std::forward<Rest>(r)...));
}
}
double PhaseSpacePoint::probability_in_jet(
std::vector<fastjet::PseudoJet> const & Born_jets
) const{
assert(std::is_sorted(begin(Born_jets), end(Born_jets), rapidity_less{}));
assert(Born_jets.size() >= 2);
const double dy =
Born_jets.back().rapidity() - Born_jets.front().rapidity();
- const double R = jet_def_.R();
+ const double R = param.jet_R();
const int njets = Born_jets.size();
const double p_J_y_large = (njets-1)*R*R/(2.*dy);
const double p_J_y0 = njets*R/M_PI;
return min(p_J_y_large, p_J_y0, 1.);
}
int PhaseSpacePoint::sample_ng_jets(
int ng, std::vector<fastjet::PseudoJet> const & Born_jets
){
RNGWrapper<CLHEP::Ranlux64Engine> rng{ran_};
const double p_J = probability_in_jet(Born_jets);
std::binomial_distribution<> bin_dist(ng, p_J);
const int ng_J = bin_dist(rng);
weight_ *= std::pow(p_J, -ng_J)*std::pow(1 - p_J, ng_J - ng);
return ng_J;
}
std::vector<fastjet::PseudoJet>
PhaseSpacePoint::reshuffle(
std::vector<fastjet::PseudoJet> const & Born_jets,
fastjet::PseudoJet const & q
){
if(q == fastjet::PseudoJet{0, 0, 0, 0}) return Born_jets;
std::vector<fastjet::PseudoJet> jets = resummation_jet_momenta(Born_jets, q);
if(jets.empty()){
weight_ = 0;
return {};
}
// transform delta functions to integration over resummation momenta
weight_ /= Jacobian(jets, q);
return jets;
}
std::vector<int> PhaseSpacePoint::distribute_jet_partons(
int ng_jets, std::vector<fastjet::PseudoJet> const & jets
){
size_t first_valid_jet = 0;
size_t num_valid_jets = jets.size();
- const double R_eff = 5./3.*jet_def_.R();
+ const double R_eff = 5./3.*param.jet_R();
// if there is an unordered jet too far away from the FKL jets
// then extra gluon constituents of the unordered jet would
// violate the FKL rapidity ordering
if(unob_ && jets[0].delta_R(jets[1]) > R_eff){
++first_valid_jet;
--num_valid_jets;
}
else if(unof_ && jets[jets.size()-1].delta_R(jets[jets.size()-2]) > R_eff){
--num_valid_jets;
}
std::vector<int> np(jets.size(), 1);
for(int i = 0; i < ng_jets; ++i){
++np[first_valid_jet + ran_.flat() * num_valid_jets];
}
weight_ *= std::pow(num_valid_jets, ng_jets);
return np;
}
#ifndef NDEBUG
namespace{
bool tagged_FKL_backward(
std::vector<fastjet::PseudoJet> const & jet_partons
){
return std::find_if(
begin(jet_partons), end(jet_partons),
[](fastjet::PseudoJet const & p){
return p.user_index() == backward_FKL_idx;
}
) != end(jet_partons);
}
bool tagged_FKL_forward(
std::vector<fastjet::PseudoJet> const & jet_partons
){
// the most forward FKL parton is most likely near the end of jet_partons;
// start search from there
return std::find_if(
jet_partons.rbegin(), jet_partons.rend(),
[](fastjet::PseudoJet const & p){
return p.user_index() == forward_FKL_idx;
}
) != jet_partons.rend();
}
bool tagged_FKL_extremal(
std::vector<fastjet::PseudoJet> const & jet_partons
){
return tagged_FKL_backward(jet_partons) && tagged_FKL_forward(jet_partons);
}
- } // end anonymous namespace
+ } // namespace anonymous
#endif
std::vector<fastjet::PseudoJet> PhaseSpacePoint::split(
std::vector<fastjet::PseudoJet> const & jets,
int ng_jets
){
return split(jets, distribute_jet_partons(ng_jets, jets));
}
bool PhaseSpacePoint::pass_extremal_cuts(
fastjet::PseudoJet const & ext_parton,
fastjet::PseudoJet const & jet
) const{
- if(ext_parton.pt() < extpartonptmin_) return false;
- return (ext_parton - jet).pt()/jet.pt() < max_ext_soft_pt_fraction_;
+ if(ext_parton.pt() < param.min_ext_pt()) return false;
+ return (ext_parton - jet).pt()/jet.pt() < param.max_ext_soft_pt_fraction();
}
std::vector<fastjet::PseudoJet> PhaseSpacePoint::split(
std::vector<fastjet::PseudoJet> const & jets,
std::vector<int> const & np
){
assert(! jets.empty());
assert(jets.size() == np.size());
assert(pass_resummation_cuts(jets));
const size_t most_backward_FKL_idx = 0 + unob_;
const size_t most_forward_FKL_idx = jets.size() - 1 - unof_;
std::vector<fastjet::PseudoJet> jet_partons;
// randomly distribute jet gluons among jets
for(size_t i = 0; i < jets.size(); ++i){
weight_ *= splitter_.Split(jets[i], np[i]);
if(weight_ == 0) return {};
assert(
std::all_of(
begin(splitter_.get_jcons()), end(splitter_.get_jcons()),
is_jet_parton
)
);
const auto first_new_parton = jet_partons.insert(
end(jet_partons),
begin(splitter_.get_jcons()), end(splitter_.get_jcons())
);
// mark uno and extremal FKL emissions here so we can check
// their position once all emissions are generated
auto extremal = end(jet_partons);
if((unob_ && i == 0) || i == most_backward_FKL_idx){
// unordered or FKL backward emission
extremal = std::min_element(
first_new_parton, end(jet_partons), rapidity_less{}
);
extremal->set_user_index(
(i == most_backward_FKL_idx)?backward_FKL_idx:unob_idx
);
}
else if((unof_ && i == jets.size() - 1) || i == most_forward_FKL_idx){
// unordered or FKL forward emission
extremal = std::max_element(
first_new_parton, end(jet_partons), rapidity_less{}
);
extremal->set_user_index(
(i == most_forward_FKL_idx)?forward_FKL_idx:unof_idx
);
}
if(
extremal != end(jet_partons)
&& !pass_extremal_cuts(*extremal, jets[i])
){
weight_ = 0;
return {};
}
}
assert(tagged_FKL_extremal(jet_partons));
std::sort(begin(jet_partons), end(jet_partons), rapidity_less{});
if(
!extremal_ok(jet_partons)
|| !split_preserved_jets(jets, jet_partons)
){
weight_ = 0.;
return {};
}
return jet_partons;
}
bool PhaseSpacePoint::extremal_ok(
std::vector<fastjet::PseudoJet> const & partons
) const{
assert(std::is_sorted(begin(partons), end(partons), rapidity_less{}));
if(unob_ && partons.front().user_index() != unob_idx) return false;
if(unof_ && partons.back().user_index() != unof_idx) return false;
return
most_backward_FKL(partons).user_index() == backward_FKL_idx
&& most_forward_FKL(partons).user_index() == forward_FKL_idx;
}
bool PhaseSpacePoint::split_preserved_jets(
std::vector<fastjet::PseudoJet> const & jets,
std::vector<fastjet::PseudoJet> const & jet_partons
) const{
assert(std::is_sorted(begin(jets), end(jets), rapidity_less{}));
const auto split_jets = sorted_by_rapidity(cluster_jets(jet_partons));
// this can happen if two overlapping jets
// are both split into more than one parton
if(split_jets.size() != jets.size()) return false;
for(size_t i = 0; i < split_jets.size(); ++i){
// this can happen if there are two overlapping jets
// and a parton is assigned to the "wrong" jet
if(!nearby_ep(jets[i].rapidity(), split_jets[i].rapidity(), 1e-2)){
return false;
}
}
return true;
}
template<class Particle>
Particle const & PhaseSpacePoint::most_backward_FKL(
std::vector<Particle> const & partons
) const{
return partons[0 + unob_];
}
template<class Particle>
Particle const & PhaseSpacePoint::most_forward_FKL(
std::vector<Particle> const & partons
) const{
const size_t idx = partons.size() - 1 - unof_;
assert(idx < partons.size());
return partons[idx];
}
template<class Particle>
Particle & PhaseSpacePoint::most_backward_FKL(
std::vector<Particle> & partons
) const{
return partons[0 + unob_];
}
template<class Particle>
Particle & PhaseSpacePoint::most_forward_FKL(
std::vector<Particle> & partons
) const{
const size_t idx = partons.size() - 1 - unof_;
assert(idx < partons.size());
return partons[idx];
}
namespace{
bool contains_idx(
fastjet::PseudoJet const & jet, fastjet::PseudoJet const & parton
){
auto const & constituents = jet.constituents();
const int idx = parton.user_index();
return std::find_if(
begin(constituents), end(constituents),
[idx](fastjet::PseudoJet const & con){return con.user_index() == idx;}
) != end(constituents);
}
}
/**
* final jet test:
* - number of jets must match Born kinematics
* - no partons designated as nonjet may end up inside jets
* - all other outgoing partons *must* end up inside jets
* - the extremal (in rapidity) partons must be inside the extremal jets
* - rapidities must be the same (by construction)
*/
bool PhaseSpacePoint::jets_ok(
std::vector<fastjet::PseudoJet> const & Born_jets,
std::vector<fastjet::PseudoJet> const & partons
) const{
- fastjet::ClusterSequence cs(partons, jet_def_);
- const auto jets = sorted_by_rapidity(cs.inclusive_jets(jetptmin_));
+ fastjet::ClusterSequence cs(partons, param.jet_def());
+ const auto jets = sorted_by_rapidity(cs.inclusive_jets(param.jet_ptmin()));
if(jets.size() != Born_jets.size()) return false;
int in_jet = 0;
for(size_t i = 0; i < jets.size(); ++i){
assert(jets[i].has_constituents());
for(auto && parton: jets[i].constituents()){
if(is_nonjet_parton(parton)) return false;
}
in_jet += jets[i].constituents().size();
}
const int expect_in_jet = std::count_if(
partons.cbegin(), partons.cend(), is_jet_parton
);
if(in_jet != expect_in_jet) return false;
// note that PseudoJet::contains does not work here
if(! (
contains_idx(most_backward_FKL(jets), most_backward_FKL(partons))
&& contains_idx(most_forward_FKL(jets), most_forward_FKL(partons))
)) return false;
if(unob_ && !contains_idx(jets.front(), partons.front())) return false;
if(unof_ && !contains_idx(jets.back(), partons.back())) return false;
for(size_t i = 0; i < jets.size(); ++i){
assert(nearby_ep(jets[i].rapidity(), Born_jets[i].rapidity(), 1e-2));
}
return true;
}
namespace{
}
void PhaseSpacePoint::reconstruct_incoming(
std::array<Sparticle, 2> const & Born_incoming
){
std::tie(incoming_[0].p, incoming_[1].p) = incoming_momenta(outgoing_);
for(size_t i = 0; i < incoming_.size(); ++i){
incoming_[i].type = Born_incoming[i].type;
}
assert(momentum_conserved(1e-7));
}
double PhaseSpacePoint::phase_space_normalisation(
int num_Born_jets, int num_out_partons
) const{
return pow(16*pow(M_PI,3), num_Born_jets - num_out_partons);
}
bool PhaseSpacePoint::momentum_conserved(double ep) const{
fastjet::PseudoJet diff;
for(auto const & in: incoming()) diff += in.p;
for(auto const & out: outgoing()) diff -= out.p;
return nearby_ep(diff, fastjet::PseudoJet{}, ep);
}
}
diff --git a/src/main.cc b/src/main.cc
index 8766df8..28962e3 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,150 +1,142 @@
/**
* Name: main.cc
* Authors: Tuomas Hapola, Andreas Maier <andreas.maier@durham.ac.uk>
*
*/
#include <fstream>
#include <algorithm>
#include <memory>
#include <chrono>
#include <iostream>
#include "yaml-cpp/yaml.h"
-#include "LHEF/LHEF.h"
#include "RHEJ/CombinedEventWriter.hh"
+#include "RHEJ/config.hh"
+#include "RHEJ/EventReweighter.hh"
#include "RHEJ/get_analysis.hh"
+#include "LHEF/LHEF.h"
#include "RHEJ/utility.hh"
-#include "RHEJ/EventReweighter.hh"
-#include "RHEJ/config.hh"
#include "RHEJ/stream.hh"
+#include "RHEJ/YAMLreader.hh"
int event_number(std::string const & record){
size_t start = record.rfind("Number of Events");
start = record.find_first_of("123456789", start);
if(start == std::string::npos) {
throw std::invalid_argument("no event number record found");
}
const size_t end = record.find_first_not_of("0123456789", start);
return std::stoi(record.substr(start, end - start));
}
RHEJ::Config load_config(char const * filename){
try{
return RHEJ::load_config(filename);
}
catch(std::exception const & exc){
std::cerr << "Error: " << exc.what() << '\n';
std::exit(EXIT_FAILURE);
}
}
std::unique_ptr<RHEJ::Analysis> get_analysis(
YAML::Node const & parameters
){
try{
return RHEJ::get_analysis(parameters);
}
catch(std::exception const & exc){
std::cerr << "Failed to load analysis: " << exc.what() << '\n';
std::exit(EXIT_FAILURE);
}
}
int main(int argn, char** argv) {
using clock = std::chrono::system_clock;
if (argn < 3) {
std::cerr << "\n# Usage:\n./HEJ config_file input_file\n\n";
return EXIT_FAILURE;
}
const auto start_time = clock::now();
// read configuration
const RHEJ::Config config = load_config(argv[1]);
RHEJ::istream in{argv[2]};
std::unique_ptr<RHEJ::Analysis> analysis = get_analysis(
- config.analysis_parameters()
+ config.analysis_parameters
);
assert(analysis != nullptr);
LHEF::Reader reader{in};
- RHEJ::CombinedEventWriter writer{config.output(), reader.heprup};
+ RHEJ::CombinedEventWriter writer{config.output, reader.heprup};
double global_reweight = 1.;
int max_events = std::numeric_limits<int>::max();
if(argn > 3){
max_events = std::stoi(argv[3]);
const int input_events = event_number(reader.headerBlock);
global_reweight = input_events/static_cast<double>(max_events);
std::cout << "processing " << max_events
<< " out of " << input_events << " events\n";
}
-
RHEJ::EventReweighter rhej{
reader.heprup,
- config.resummation_jets().def, config.resummation_jets().min_pt,
- config.treat(),
- config.min_extparton_pt(), config.max_ext_soft_pt_fraction(),
- config.log_correction(),
- config.Higgs_coupling()
+ config
};
- if(config.RanLux_init()){
- RHEJ::PhaseSpacePoint::reset_ranlux(*config.RanLux_init());
+ if(config.RanLux_init){
+ RHEJ::PhaseSpacePoint::reset_ranlux(*config.RanLux_init);
}
int nevent = 0;
std::array<int, RHEJ::event_type::last_type + 1>
nevent_type{0}, nfailed_type{0};
// Loop over the events in the inputfile
while(reader.readEvent()){
- std::cout << "#event " << nevent << std::endl;
// reweight events so that the total cross section is conserved
reader.hepeup.setWeight(0, global_reweight * reader.hepeup.weight());
- if(nevent == max_events) {
- std::cout << "max #event reached " << nevent << " " << max_events << std::endl;
- break;
- }
+ if(nevent == max_events) break;
nevent++;
if (nevent % 10000 == 0)
std::cout << "event number " << nevent << std::endl;
// calculate rHEJ weight
RHEJ::Event FO_event{
RHEJ::UnclusteredEvent{reader.hepeup},
- config.fixed_order_jets().def, config.fixed_order_jets().min_pt,
+ config.fixed_order_jets.def, config.fixed_order_jets.min_pt,
};
auto resummed_events = rhej.reweight(
FO_event,
- config.trials(), config.scale_gen()
+ config.trials, config.scale_gen
);
++nevent_type[FO_event.type()];
if(resummed_events.empty()) ++nfailed_type[FO_event.type()];
for(auto const & ev: resummed_events){
//TODO: move pass_cuts to after phase space point generation
if(analysis->pass_cuts(ev, FO_event)){
analysis->fill(ev, FO_event);
writer.write(ev);
}
}
} // main event loop
using namespace RHEJ::event_type;
std::cout<< "Events processed: " << nevent << '\n';
for(size_t ev_type = first_type; ev_type <= last_type; ++ev_type){
std::cout << '\t' << names[ev_type] << ": " << nevent_type[ev_type]
<< ", failed to reconstruct " << nfailed_type[ev_type]
<< '\n';
}
std::chrono::duration<double> run_time = (clock::now() - start_time);
std::cout << "\nTask Runtime: " << run_time.count() << " seconds.\n";
}
diff --git a/t/check_res.cc b/t/check_res.cc
index 623636a..c8f6c8a 100644
--- a/t/check_res.cc
+++ b/t/check_res.cc
@@ -1,71 +1,72 @@
#include <iostream>
#include "LHEF/LHEF.h"
#include "RHEJ/stream.hh"
#include "RHEJ/EventReweighter.hh"
namespace{
const fastjet::JetDefinition jet_def{fastjet::kt_algorithm, 0.4};
const fastjet::JetDefinition Born_jet_def{jet_def};
constexpr double Born_jetptmin = 30;
constexpr double extpartonptmin = 30;
constexpr double max_ext_soft_pt_fraction =
std::numeric_limits<double>::infinity();
constexpr double jetptmin = 35;
constexpr bool log_corr = false;
using EventTreatment = RHEJ::EventTreatment;
using namespace RHEJ::event_type;
RHEJ::EventTreatMap treat{
{no_2_jets, EventTreatment::discard},
{bad_final_state, EventTreatment::discard},
{nonFKL, EventTreatment::discard},
{unof, EventTreatment::discard},
{unob, EventTreatment::discard},
{FKL, EventTreatment::reweight}
};
};
int main(int argn, char** argv) {
if(argn == 5 && std::string(argv[4]) == "uno"){
--argn;
treat[unof] = EventTreatment::reweight;
treat[unob] = EventTreatment::reweight;
treat[FKL] = EventTreatment::discard;
}
if(argn != 4){
std::cerr << "Usage: check_res eventfile xsection tolerance [uno]";
return EXIT_FAILURE;
}
const double xsec_ref = std::stod(argv[2]);
const double tolerance = std::stod(argv[3]);
RHEJ::istream in{argv[1]};
LHEF::Reader reader{in};
- RHEJ::EventReweighter rhej{
- reader.heprup,
- jet_def, jetptmin,
- treat,
- extpartonptmin, max_ext_soft_pt_fraction,
- log_corr,
- RHEJ::HiggsCouplingSettings{}
- };
+ RHEJ::Config conf;
+ conf.resummation_jets = RHEJ::JetParameters{jet_def, jetptmin};
+ conf.treat = treat;
+ conf.min_extparton_pt = extpartonptmin;
+ conf.max_ext_soft_pt_fraction = max_ext_soft_pt_fraction;
+ conf.log_correction = log_corr;
+ conf.Higgs_coupling = RHEJ::HiggsCouplingSettings{};
+
+ RHEJ::EventReweighter rhej(reader.heprup, conf);
double xsec = 0.;
while(reader.readEvent()){
RHEJ::Event ev{
RHEJ::UnclusteredEvent{reader.hepeup},
Born_jet_def, Born_jetptmin
};
auto resummed_events = rhej.reweight(ev, 10);
for(auto const & ev: resummed_events) xsec += ev.central().weight;
}
if(std::abs(xsec - xsec_ref) > tolerance){
std::cerr << "cross section is off: "
<< xsec << " != " << xsec_ref
<< " +- " << tolerance << '\n';
return EXIT_FAILURE;
}
}
diff --git a/t/test_ME_h_3j.cc b/t/test_ME_h_3j.cc
index dffaa38..c8fad15 100644
--- a/t/test_ME_h_3j.cc
+++ b/t/test_ME_h_3j.cc
@@ -1,93 +1,99 @@
#include "LHEF/LHEF.h"
+#include "RHEJ/config.hh"
#include "RHEJ/MatrixElement.hh"
#include "RHEJ/Event.hh"
struct Event{
std::array<RHEJ::Sparticle, 2> incoming;
std::vector<RHEJ::Sparticle> outgoing;
Event(
RHEJ::Sparticle in1, RHEJ::Sparticle in2,
std::initializer_list<RHEJ::Sparticle> out
):
incoming{std::move(in1), std::move(in2)},
outgoing{out}
{}
};
constexpr
RHEJ::pid::ParticleID PDG(int id){
return static_cast<RHEJ::pid::ParticleID>(id);
}
constexpr double alpha_s = 0.113559;
constexpr double mu = 125.;
constexpr double R = 0.4;
constexpr double min_jet_pt = 50.;
constexpr auto jet_def = fastjet::antikt_algorithm;
constexpr double ep = 1e-4;
void dump(Event const & ev){
LHEF::Writer writer{std::cerr};
std::cerr << std::setprecision(15);
RHEJ::UnclusteredEvent tmp;
tmp.incoming = ev.incoming;
tmp.outgoing = ev.outgoing;
tmp.central = {mu, mu, 0.};
RHEJ::Event out_ev{std::move(tmp), {jet_def, R}, min_jet_pt};
writer.hepeup = to_HEPEUP(std::move(out_ev), nullptr);
writer.writeEvent();
}
int main(){
std::vector<Event> events = {
/*
* reference matrix elements obtained from traditional HEJ (svn r3355)
* weights correspond to shat2*wt/(pdfPtr->pdfta*pdfPtr->pdftb)
* at the end of MEt2 in HJets.cxx
*/
#include "ME_test_events.dat"
};
const std::vector<double> ref_weights{
1.20840366448943e-08,3.41482815561959e-18,4.09113550770465e-12,4.62704699562129e-15,4.48439126356004e-15,1.87972263060254e-12,1.44306589954128e-14,9.10660553817556e-13,6.78185181417658e-13,2.2313219279205e-14,5.04225136522914e-10,1.15445795400542e-13,4.25305992011228e-15,6.34464495221583e-11,8.1504882635896e-09,8.13050604628519e-10,1.16718768515638e-12,2.10641257506331e-08,6.62448031524987e-23,4.3319311109536e-07,1.20944494921349e-15,5.92539274973405e-05,4.4796169513938e-17,1.49273221119393e-15,2.43311569643869e-18,2.402863950606e-12,1.0620402696538e-11,5.35907540952987e-14,1.23031328706173e-12,2.79984692016006e-15,9.15681008462036e-19,6.82192590709917e-19,7.89237067022333e-13,1.86125787460036e-14,6.46979689455398e-07,3.04911830916725e-15,8.13163686285418e-15,1.53766124466997e-14,8.32276518653951e-14,8.88400099785712e-11,8.91102728936822e-06,1.80107644544759e-15,2.10582866365414e-09,3.10947796493188e-17,3.91243813845236e-15,3.26654480787734e-17,9.5447871679842e-14,2.59793669360488e-15,4.96134344054012e-13,5.81162371703576e-14,1.111167877034e-09,2.79109572058797e-16,4.46160513513727e-16,6.75218397576417e-15,2.68260561114305e-11,4.28989454505788e-16,5.8329868340234e-16,2.2024897389957e-09,2.57397955688743e-15,2.44654345522128e-14,2.30866752912176e-14,1.41827747056589e-07,1.08893147410797e-14,4.03382910318587e-11,3.1389869623674e-10,3.90505557430021e-13,1.08295237971538e-12,7.454591488958e-15,7.54483306433453e-14,1.02908259302562e-15,5.63531574394432e-14,6.30249429292698e-11,4.53762691808614e-13,1.89024041595359e-16,6.8158270448436e-15,1.14399844221906e-12,8.90256332512462e-11,6.06548092223796e-17,9.98362270779565e-12,4.59859716748231e-15,2.15099414771066e-10,2.11591109618363e-13,4.9742178019335e-09,1.33845681137089e-10,2.71186491627684e-16,8.86739836718398e-13,1.8249669781697e-14,1.92215499935624e-13,5.63538105112205e-14,4.14171568963499e-12,2.2717979957039e-15,5.55611156772101e-15,1.28364738716082e-16,5.3851134765245e-12,1.24211103260246e-08,4.83232530709888e-17,0.000521569751168655,1.6806219324588e-15,6.59977348355555e-11,9.1627970683281e-14,2.76820118228537e-12,4.0198982918336e-11,1.48426883756103e-18,1.40114232815435e-18,1.7965991343524e-11,7.6977628175923e-10,4.62196685302415e-14,2.69246069544232e-08,1.51516950568948e-13,6.99496684443045e-13,5.18573546306991e-16,0.0434630460883225,1.9837330600509e-23,2.67017601462925e-12,9.8878856049861e-16,8.72580364190897e-11,9.78094461016429e-06,8.71781003862465e-17,1.1559862791241e-08,4.84083438123941e-11,0.0139742563571754,1.99847601444777e-13,3.04915596353023e-17,5.93151845056274e-16,2.17435618150856e-14,5.33225221812805e-08,3.87773807827851e-14,4.50810202343348e-08,1.21607462589437e-08,3.1594598104258e-13,3.28656273761685e-16,2.50210924939855e-21,2.38126296013289e-13,1.25433376653286e-11,2.14322725557091e-14,1.49146107213853e-09,1.242585653879e-15,3.55954759815053e-17,3.58323190858796e-10,4.51037144634267e-14,7.55931651143187e-09,5.37698824199559e-14,7.38868781004529e-14,1.69357650230295e-11,5.80639629823124e-10,7.4837350747944e-17,6.96956083393151e-16,1.81834207579059e-10,2.82540028744915e-12,4.0395726561383e-13,1.79694539029015e-12,1.31041890677814e-16,1.30438189219159e-07,1.43221371664219e-10,9.114047729275e-16,7.34577355123687e-09,3.22593068239571e-15,4.15681922353836e-15,3.36408379142654e-16,1.44480854726148e-11,1.01363611458694e-13,1.00219358430676e-12,0.00338137229726986,4.29548017717404e-15,2.60395354258443e-14,4.1476296627427e-14,1.06855911096978e-13,8.22439039784712e-11,2.73629652512136e-10,5.15659349602634e-11,1.01584718933351e-13,6.94380398977803e-16,2.18931000347143e-18,3.07933496617785e-09,1.66390942837878e-16,3.52525907142114e-13,3.78080647432571e-14,1.17556440172277e-12,6.59751630435329e-17,1.21755902521401e-08,2.55450721249666e-11,1.53256550428156e-14,1.08380893991568e-12,4.16098986326189e-13,2.90205083341855e-14,5.511460594056e-18,1.57699398911427e-16,7.00104401760928e-13,3.58046798793545e-12,2.01229361268661e-12,3.73614518690553e-07,2.14710426845508e-14,3.70105600162546e-13,7.98071394035332e-15,7.37834963791502e-16,1.60529982053429e-09,1.08256973923745e-12,1.0334353499219e-13,9.49543099778791e-11,1.9115591364306e-12,4.0448657562838e-16,8.71422438179998e-15,1.25631778664749e-16,3.14479096095934e-19,2.64428535684163e-16,1.12107615349188e-11,1.23625298812219e-13,4.01428912903254e-13,2.70797308155832e-11,6.56279497820654e-09,7.13734059806893e-16,0.000782868291989126,3.76614026148548e-16,1.26257000484765e-13,9.58631950869197e-13,8.31708875806124e-11,2.34133301418612e-13,9.56863619261736e-14,4.64712032868663e-12,2.86185199150703e-12,1.33576465609689e-11,1.10079981208014e-15,1.0127254462106e-12,1.1462054990501e-12,6.6945137657857e-11,5.58956247731427e-17,9.55921087729154e-12,2.34217482968982e-13,9.06915368555449e-19,5.71005344841003e-15,7.30755001164554e-09,6.21879071656432e-07,3.18226338142145e-17,7.85187718829052e-15,1.12784019414768e-13,1.26620458266236e-12,3.69177699852588e-14,5.15075992359208e-08,4.92072565553936e-15,1.85781482577606e-18,4.45444190278706e-16,1.26266755594178e-13,2.4288203970545e-16,3.05176309462854e-13,1.10490541122231e-16,8.47749453725764e-16,5.15877353528789e-11,5.24254149207253e-17,1.91355494316452e-10,5.00556344079427e-17,2.17154626918891e-15,8.84358943960976e-15,3.61414423657153e-11,4.82735747825927e-09,1.29064865560832e-13,8.42127739585314e-10,3.92906216459766e-16,6.04446459041361e-17,5.89524177334148e-12,5.46194519536606e-19,1.34088171433487e-11,5.52860041827642e-15,1.75477788501097e-15,1.73667838135065e-16,1.65397026290053e-13,1.12185521855334e-09,6.08386662697057e-17,4.59141650497559e-07,1.5209325219688e-11,2.23037744763897e-13,2.01952877105987e-13,6.8597135743949e-17,1.21998302502671e-11,3.21171910404898e-17,5.26021980482437e-15,7.19705632175135e-19,1.20963419308456e-09,6.88528237531901e-13,1.98848279147693e-11,4.01262000581642e-12,5.20247739003617e-13,1.30428205622828e-14,4.11298291694491e-13,5.52043003142038e-10,1.23093415613032e-16,7.36616975809533e-17,3.45364902177034e-16,4.34985181424009e-08,5.38804276057675e-14,9.48300760869968e-13,1.22337104642822e-09,8.35787040119371e-14,1.55423397182344e-15,1.42203125672685e-13,3.18903277676011e-13,3.88652741986258e-15,7.04896809011702e-18,1.32646740227354e-21,7.99231856556843e-13,5.95802234870006e-09,1.65149306543534e-12,1.33064116256099e-11,1.56832702886549e-12,1.10299934631458e-08,3.67898989067657e-16,7.84682358054423e-17,2.57971628718788e-09,8.33182695406546e-17,1.18568992167241e-10,1.84355449893326e-12,2.55066898328171e-13,2.83673294248314e-14,1.78606190612042e-12,3.58348766614931e-12,4.59943073492537e-16,9.51522624162865e-13,8.0286195911246e-14,1.36695977212813e-16,2.66996900743536e-13,1.18874419459462e-15,4.20697505402443e-07,1.44157427471053e-12,3.88352207261609e-12,1.10352682706254e-15,9.16382540998255e-16,1.6918487768822e-14,6.27001020277801e-13,1.19982339734628e-15,2.08524585760556e-15,3.98635216491517e-11,2.29164410091261e-16,6.59993812570474e-14,9.09720299660866e-19,1.00791143935241e-13,3.48282488442434e-15,3.82462701684145e-11,1.82912920125976e-14,2.35934504263123e-12,3.07876467756239e-11,3.01958860729077e-05,1.34442938440306e-12,1.98172170171169e-11,2.54803366934403e-14,4.63525528427102e-13,1.98623090357032e-11,1.17532063246858e-12,1.62645374532443e-16,2.23093836031326e-11,5.23718977936426e-13,6.30254161980384e-15,5.64457070654369e-16,5.8598582297477e-15,1.54121478101166e-11,2.54757492800786e-11,7.24784320481052e-13,7.10590291356503e-11,1.90012029508776e-12,5.38421849395334e-05,9.2027530054952e-13,0.00802523961864568,1.69971085315301e-12,4.17128853468654e-15,2.58531014487319e-15,6.72871249369096e-12,3.68392430578061e-16,1.56192266889718e-14,8.09758960836169e-16,1.33670176619002e-07,3.40402526854793e-10,7.14029639915786e-15,1.15907463202726e-14
};
const std::vector<double> ref_virt{
0.000407437434887122,0.0616303680115081,0.0619338272462471,0.00113600815259533,0.0611805205486735,0.000565698082480416,0.516976611025519,0.0361140019339901,0.00145895360905874,0.134071980986426,0.000248975936203567,0.199294625870235,0.24358305091454,4.74361172738652e-05,5.89666196640687e-05,0.00531027816302915,0.000200243383490462,0.0805261711344379,0.00120027603203917,0.00201705178179895,0.339181495419129,0.000229863490455131,0.0523929260778993,0.000263057002724373,0.00244241108460007,0.0261467924657004,5.9657372131903e-05,0.200512468910312,0.00810099141722299,0.013973033333956,0.0108154079325531,0.158574821336736,0.00070998197888614,0.000498608284914822,3.73054997210496e-05,0.0589374030166269,0.00230622721548646,0.0339477696166811,0.000912463632412847,0.000736710687806361,0.00409015383244036,0.245951477936874,0.0837392661445892,0.222078993106222,0.00532590926455614,0.625630979237125,0.0496003388518398,0.10116468200925,0.0661786669164834,0.0210544045965245,0.0244625178289293,0.0146510511459362,0.101257018174142,0.00316763508016474,0.00143243489499069,0.333592621341247,0.00370907687545401,0.00213872056006003,0.01900030889465,0.167144065343861,2.6100961817368e-05,4.91550277446228e-05,0.0166499896061438,0.00011398434602661,0.000359768751250008,0.00225147558163185,0.0317147645964709,0.0842595514695342,0.35407612826878,0.00010526694382132,0.0430608610020923,3.5715013356257e-05,0.000838215519554185,0.00192018265054966,0.0713712284182796,0.000485232329561933,0.00152471141515176,0.000311862603200811,0.166619420201183,0.0199021050517686,1.41779057397457e-05,0.0017318628596011,0.00053760812759845,0.0686125677803084,0.0532620439395034,0.00166666380089786,0.0113533421860016,0.000109349820296255,0.0115667016173654,0.00173679164546385,0.0256607191277514,0.00120155627964714,0.0111815333349668,0.00349052851306921,0.00531735228893806,0.00152975285273546,4.66037248418355e-05,0.0425850611539657,0.00117697776465851,1.23387751381228e-05,0.0038237470220905,0.0905644410585002,0.02820127090728,0.00024367136851271,0.147636957219027,0.000593136877076053,0.0618471045067722,9.07687985864349e-06,0.000158960279301719,0.0887358461047651,0.0332353914977947,7.4341716367417e-06,0.000892008177580303,0.000741022113249675,0.00237741099974918,0.00354813689304541,0.00074173961384706,0.00467141577324516,0.00842296482521057,0.00821661392007147,4.83792120557372e-05,0.00425252516494632,0.000432204419963046,0.00586736518573752,0.000956530707046858,0.000236851602228008,0.0892427215701044,1.38830962250345e-05,0.0080267826500828,0.284615916615109,0.000228095910528196,0.000135342214864163,7.55341699407512e-06,0.000571884401074523,0.0101768016413147,0.0171951107578717,0.00189669876455143,0.00394930354845142,0.00328294862282636,0.00123193340562429,0.00331783483858544,0.00319051646342221,0.00155129659005506,8.87358953340508e-05,0.27623170363077,0.000223827470760779,0.0568015505265356,0.000286151801691539,0.0193226057191209,0.00123755083758374,0.000465248541258071,0.0760142560624272,0.00112490607994365,0.000144842352216183,0.197405681090406,0.00129883979140284,0.0930965339402953,0.0010308437485118,0.670013359364299,0.00432667098624779,0.0454915871138651,0.00251703872973342,0.00423441033466031,0.000345157767746845,0.00161415356368555,0.00416069958683314,0.00164939718639514,0.0111406419016027,0.00655421252542946,0.00851532238518754,0.00348709627275328,0.496059905302338,0.0371917367183897,0.000211531938236732,0.000258942974591912,0.17759337052515,0.00418622722335427,0.166120697713642,0.00360502919950296,0.000407414278464457,0.0360738279541873,0.0288893174873495,0.00047259015965458,1.56547248986137e-05,0.834956154090444,0.00732703650642937,0.00474657800944094,0.00273096554923287,0.257207154892208,0.00469808491585188,0.000270576144489275,0.000136075839471612,0.097205919234904,0.000607126031374257,0.000136619984636834,0.000160087925098193,0.0073858227644151,0.538982397271589,0.00336284303209108,0.00152656630103797,0.367113302445716,7.48038626150403e-05,2.60037367946894e-05,4.68016275421979e-05,0.000158257654442151,0.000139074963089943,0.000665698879408135,0.000343142682314476,0.0686327476602143,0.000242720484154181,0.0343708294206813,0.00114889968298977,0.0586454267607763,0.0681515891243611,0.00825429790468652,0.023992046337532,0.0176721744671367,0.000118812692493978,0.152442537631382,0.017153140472422,0.0064172004743378,3.15311961394686e-05,0.0176719977165195,0.00523267370956132,0.00696013339412051,0.0283129688131134,0.000387153677372906,0.00691199037138631,0.000146275451696295,0.701230156661611,0.000192846626056869,0.000164329434653947,0.00161262788918379,0.138649850457724,0.0298984433917698,0.0318122273046375,3.04827880239274e-05,0.000447390422746664,0.00113026494701542,0.00113285595566244,2.89098339981399e-05,0.00113856357833898,0.0539144571449436,0.0708152617112735,0.000146823107858066,0.0226524231026193,0.00337461891944858,0.000951319767163979,0.00173528759879105,0.027553837556441,0.000644790987241654,0.00202675597720372,0.0904812026317863,0.000121859990107361,0.0778263959001868,0.0078676495423855,0.00106041104696191,0.0460181415526085,0.111418229601818,0.00485578450515022,0.000301615731939099,0.0991074788208953,0.000545043001929007,0.00699096247420379,0.203553031240112,0.00129391506623192,0.0163036481873179,9.84784360850182e-06,0.0011930992876943,0.000233138513444116,0.00327134762224621,0.00934510369593952,0.0257690022271133,0.0586620958023085,0.0044269686967688,0.00458204111385776,0.000575173870997244,0.0196091953126155,0.0172446254918132,0.0023874923763825,0.00203444177442346,0.00590189106361814,0.160798676736245,0.000218465854877618,0.0449130791723244,0.0221907455403962,0.00577930006864582,4.68129848124974e-05,4.39088532565896e-05,0.0957291068496414,0.000222196152405895,0.00244492299475677,0.0649283175892222,0.00246575641284538,0.00395895850035338,0.452609135498808,2.18247701431579e-05,0.000103691495491759,0.0300254483476907,0.000997825085990438,0.00120168803041095,0.000488310402876861,5.02375648302248e-05,0.0889218155230037,0.886196353445691,0.537472442381394,0.000989158503397272,0.00585452117968649,0.000166646041974894,0.0559913557856292,0.271624614149917,1.9604193016588e-05,0.00400455993655262,0.000719953658022318,0.00769221521719457,0.0122222590022294,0.00869539856191144,0.00665334452394116,0.00269456106141176,0.0203144580365219,1.06269256412071e-05,0.00266305904353431,0.000866750257077464,0.0118678506617259,0.00774140571086026,0.472668086097713,0.00449314655439557,0.000363054262255041,0.000123958362353204,0.0593128481039698,6.49758497533422e-05,0.0147733538718899,0.000181422709422017,0.124358363237549,0.0149418567595413,0.000496790567694211,0.00319609174497007,0.171371757877329,0.000132314177013318,0.000118421517677613,0.0384411149022143,0.0560023977555578,0.000545951922843868,0.00923849055867683,7.42750022847054e-05,0.0034657141222543,0.0814951536826408,0.000247436489650107,0.00279135741337402,0.128217103654628,0.000239656955359697,0.0286081920788208,0.0264861644616376,0.000700223039958121,0.000224261722502375,0.206999869456071,0.0245477336638465,0.00020080171595025,0.000534370708560753,0.00114853261836608,0.0140588914482069,0.0491695416950957,0.0219392429988939,0.000187573794241001,2.76073824918907e-05,0.0177905351398601,0.0227102533101537,0.0156338659659345,0.0045130866637909,0.0118789100672146,0.0684121072806861
};
+ RHEJ::Config config;
+ config.resummation_jets.def = fastjet::JetDefinition(jet_def, R);
+ config.resummation_jets.min_pt = min_jet_pt;
+ config.log_correction = false;
+ config.Higgs_coupling = RHEJ::HiggsCouplingSettings{};
+
RHEJ::MatrixElement ME{
[](double){ return alpha_s; },
- {jet_def, R}, min_jet_pt, false,
- RHEJ::HiggsCouplingSettings{}
+ config
};
assert(events.size() == ref_weights.size());
for(size_t i = 0; i < events.size(); ++i){
std::sort(
begin(events[i].outgoing), end(events[i].outgoing),
RHEJ::rapidity_less{}
);
const double our_ME = ME.tree(
mu, events[i].incoming, events[i].outgoing, true
);
const double deviation = our_ME/ref_weights[i] - 1.;
if(std::abs(deviation) > ep){
std::cerr
<< "Matrix element deviates by factor of " << 1+deviation << ":\n"
"Is " << our_ME << ", should be " << ref_weights[i] << "\n"
"Event:\n";
dump(events[i]);
return EXIT_FAILURE;
}
const double our_virt = ME.virtual_corrections(
mu, events[i].incoming, events[i].outgoing
);
const double virt_deviation = our_virt/ref_virt[i] - 1.;
if(std::abs(virt_deviation) > ep){
std::cerr
<< "Virtual corrections deviate by factor of " << 1+virt_deviation << ":\n"
"Is " << our_virt << ", should be " << ref_virt[i] << "\n"
"Event:\n";
dump(events[i]);
return EXIT_FAILURE;
}
}
}
diff --git a/t/test_ME_hjets_mt174.cc b/t/test_ME_hjets_mt174.cc
index e46afbc..4c54a60 100644
--- a/t/test_ME_hjets_mt174.cc
+++ b/t/test_ME_hjets_mt174.cc
@@ -1,84 +1,90 @@
#include "LHEF/LHEF.h"
#include "RHEJ/MatrixElement.hh"
#include "RHEJ/Event.hh"
struct Event{
double weight;
std::array<RHEJ::Sparticle, 2> incoming;
std::vector<RHEJ::Sparticle> outgoing;
Event(
double wt,
RHEJ::Sparticle in1, RHEJ::Sparticle in2,
std::initializer_list<RHEJ::Sparticle> out
):
weight{wt},
incoming{std::move(in1), std::move(in2)},
outgoing{out}
{}
};
constexpr
RHEJ::pid::ParticleID PDG(int id){
return static_cast<RHEJ::pid::ParticleID>(id);
}
constexpr double alpha_s = 0.112654;
constexpr double mu = 125.;
constexpr double R = 0.4;
constexpr double min_jet_pt = 35.;
constexpr auto jet_def = fastjet::antikt_algorithm;
constexpr double ep = 1e-4;
constexpr double alpha_s_mH_RHEJ = 0.113559;
void dump(Event const & ev){
LHEF::Writer writer{std::cerr};
std::cerr << std::setprecision(15);
RHEJ::UnclusteredEvent tmp;
tmp.incoming = ev.incoming;
tmp.outgoing = ev.outgoing;
tmp.central = {mu, mu, 0.};
RHEJ::Event out_ev{std::move(tmp), {jet_def, R}, min_jet_pt};
writer.hepeup = to_HEPEUP(std::move(out_ev), nullptr);
writer.writeEvent();
}
int main(){
std::vector<Event> events = {
/*
* reference matrix elements obtained from traditional HEJ (svn r3355)
* weights correspond to shat2*wt/(pdfPtr->pdfta*pdfPtr->pdftb)
* at the end of MEt2 in HJets.cxx
*/
#include "ME_hjets_mt174.dat"
};
+ RHEJ::Config config;
+ config.resummation_jets.def = fastjet::JetDefinition(jet_def, R);
+ config.resummation_jets.min_pt = min_jet_pt;
+ config.log_correction = false;
+
RHEJ::HiggsCouplingSettings settings;
settings.mt = 174.;
settings.use_impact_factors = false;
settings.mb = 5.;
settings.include_bottom = true;
+ config.Higgs_coupling = settings;
RHEJ::MatrixElement ME{
[](double){ return alpha_s; },
- {jet_def, R}, min_jet_pt, false, settings
+ config
};
for(size_t i = 0; i < events.size(); ++i){
std::sort(
begin(events[i].outgoing), end(events[i].outgoing),
RHEJ::rapidity_less{}
);
const double our_ME = ME.tree(
mu, events[i].incoming, events[i].outgoing, true
);
const double deviation = our_ME/events[i].weight - 1.;
if(std::abs(deviation) > ep){
std::cerr
<< "Matrix element deviates by factor of " << 1+deviation << ":\n"
"Is " << our_ME << ", should be " << events[i].weight << "\n"
"Event:\n";
dump(events[i]);
return EXIT_FAILURE;
}
}
}
diff --git a/t/test_psp.cc b/t/test_psp.cc
index 875f258..434d33f 100644
--- a/t/test_psp.cc
+++ b/t/test_psp.cc
@@ -1,62 +1,66 @@
#include "LHEF/LHEF.h"
#include "RHEJ/stream.hh"
+#include "RHEJ/config.hh"
#include "RHEJ/event_types.hh"
#include "RHEJ/Event.hh"
#include "RHEJ/PhaseSpacePoint.hh"
namespace{
constexpr int max_trials = 100;
constexpr double extpartonptmin = 45.;
constexpr double max_ext_soft_pt_fraction =
std::numeric_limits<double>::infinity();
const fastjet::JetDefinition jet_def{fastjet::kt_algorithm, 0.4};
constexpr double min_jet_pt = 50;
};
int main(int argn, char** argv) {
if(argn != 2){
std::cerr << "Usage: test_psp eventfile";
return EXIT_FAILURE;
}
RHEJ::istream in{argv[1]};
LHEF::Reader reader{in};
LHEF::Writer writer{std::cerr};
writer.heprup = reader.heprup;
+
+ RHEJ::Config conf;
+ conf.resummation_jets = RHEJ::JetParameters{jet_def, min_jet_pt};
+ conf.min_extparton_pt = extpartonptmin;
+ conf.max_ext_soft_pt_fraction = max_ext_soft_pt_fraction;
+
while(reader.readEvent()){
const RHEJ::Event ev{
RHEJ::UnclusteredEvent{reader.hepeup},
jet_def, min_jet_pt
};
for(int trial = 0; trial < max_trials; ++trial){
- RHEJ::PhaseSpacePoint psp{
- ev, jet_def, min_jet_pt,
- extpartonptmin, max_ext_soft_pt_fraction
- };
+ RHEJ::PhaseSpacePoint psp(ev, conf);
if(psp.weight() != 0){
RHEJ::UnclusteredEvent tmp_ev;
tmp_ev.incoming = psp.incoming();
tmp_ev.outgoing = psp.outgoing();
tmp_ev.central = {0,0,0};
RHEJ::Event out_ev{
std::move(tmp_ev),
jet_def, min_jet_pt
};
if(out_ev.type() != ev.type()){
using RHEJ::event_type::names;
std::cerr << "Wrong class of phase space point:\n"
"original event of class " << names[ev.type()] << ":\n";
writer.hepeup = reader.hepeup;
writer.writeEvent();
std::cerr << "Phase space point of class " << names[out_ev.type()] << ":\n";
writer.hepeup = to_HEPEUP(out_ev, &writer.heprup);
writer.writeEvent();
return EXIT_FAILURE;
}
}
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jan 21, 1:46 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4243523
Default Alt Text
(121 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment