Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8725689
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
37 KB
Subscribers
None
View Options
diff --git a/include/RHEJ/config.hh b/include/RHEJ/config.hh
index bab25fb..e61f466 100644
--- a/include/RHEJ/config.hh
+++ b/include/RHEJ/config.hh
@@ -1,114 +1,260 @@
/** \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 "RHEJ/ScaleFunction.hh"
#include "RHEJ/optional.hh"
#include "RHEJ/output_formats.hh"
#include "RHEJ/event_classes.hh"
#include "RHEJ/HiggsCouplingSettings.hh"
+#include "RHEJ/exceptions.hh"
+#include "RHEJ/utility.hh"
#include "yaml-cpp/yaml.h"
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<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_;
};
/**
* \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 EventClass keys and mapped values EventTreatment
*
* If called upon with EventTreatMap.at(EventClass) it will return the treatment which has
* been specified for that EventClass.
*/
using EventTreatMap = std::map<event_class::EventClass, EventTreatment>;
/**! \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.
*/
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 */
bool unweight; /**< Unweight On or Off */
std::vector<OutputFile> output; /**< Output File Type */
optional<std::string> RanLux_init; /**< Ranlux File Choice*/
EventTreatMap treat; /**< Event Treat Map? */
YAML::Node analysis_parameters; /**< Analysis Parameters */
//! Settings for Effective Higgs-Gluon Coupling
HiggsCouplingSettings Higgs_coupling;
};
Config load_config(std::string const & config_file);
+
+ template<typename T, typename... YamlNames>
+ void set_from_yaml(
+ T & setting,
+ YAML::Node const & yaml, YamlNames const & ... names
+ );
+
+ template<typename T, typename... YamlNames>
+ void set_from_yaml_if_defined(
+ T & setting,
+ YAML::Node const & yaml, YamlNames const & ... names
+ );
+
+ namespace detail{
+ template<typename Scalar>
+ void set_from_yaml(Scalar & setting, YAML::Node const & yaml){
+ assert(yaml);
+ if(!yaml.IsScalar()){
+ throw invalid_type{"value is not a scalar"};
+ }
+ try{
+ setting = yaml.as<Scalar>();
+ }
+ catch(...){
+ throw invalid_type{
+ "value " + yaml.as<std::string>()
+ + " cannot be converted to a " + type_string(setting)
+ };
+ }
+ }
+
+ template<typename T>
+ void set_from_yaml(optional<T> & setting, YAML::Node const & yaml){
+ T tmp;
+ set_from_yaml(tmp, yaml);
+ setting = tmp;
+ }
+
+ template<typename T>
+ void set_from_yaml(std::vector<T> & setting, YAML::Node const & yaml){
+ assert(yaml);
+ // special case: treat a single value like a vector with one element
+ if(yaml.IsScalar()){
+ setting.resize(1);
+ return set_from_yaml(setting.front(), yaml);
+ }
+ if(yaml.IsSequence()){
+ setting.resize(yaml.size());
+ for(size_t i = 0; i < setting.size(); ++i){
+ set_from_yaml(setting[i], yaml[i]);
+ }
+ return;
+ }
+ throw invalid_type{""};
+ }
+
+ void set_from_yaml(fastjet::JetAlgorithm & setting, YAML::Node const & yaml);
+ void set_from_yaml(EventTreatment & setting, YAML::Node const & yaml);
+
+ inline
+ void set_from_yaml(YAML::Node & setting, YAML::Node const & yaml){
+ setting = yaml;
+ }
+
+ template<typename T, typename FirstName, typename... YamlNames>
+ void set_from_yaml(
+ T & setting,
+ YAML::Node const & yaml, FirstName const & name,
+ YamlNames && ... names
+ ){
+ if(!yaml[name]) throw missing_option{""};
+ set_from_yaml(
+ setting,
+ yaml[name], std::forward<YamlNames>(names)...
+ );
+ }
+
+ template<typename T>
+ void set_from_yaml_if_defined(T & setting, YAML::Node const & yaml){
+ return set_from_yaml(setting, yaml);
+ }
+
+ template<typename T, typename FirstName, typename... YamlNames>
+ void set_from_yaml_if_defined(
+ T & setting,
+ YAML::Node const & yaml, FirstName const & name,
+ YamlNames && ... names
+ ){
+ if(!yaml[name]) return;
+ set_from_yaml_if_defined(
+ setting,
+ yaml[name], std::forward<YamlNames>(names)...
+ );
+ }
+ }
+
+ template<typename T, typename... YamlNames>
+ void set_from_yaml(
+ T & setting,
+ YAML::Node const & yaml, YamlNames const & ... names
+ ){
+ try{
+ detail::set_from_yaml(setting, yaml, names...);
+ }
+ catch(invalid_type const & ex){
+ throw invalid_type{
+ "In option " + join(": ", names...) + ": value " + ex.what()
+ + " cannot be converted to a " + type_string(setting)
+ };
+ }
+ catch(missing_option const &){
+ throw missing_option{
+ "No entry for mandatory option " + join(": ", names...)
+ };
+ }
+ catch(std::invalid_argument const & ex){
+ throw missing_option{
+ "In option " + join(": ", names...) + ":"
+ " invalid value " + ex.what()
+ };
+ }
+ }
+
+ template<typename T, typename... YamlNames>
+ void set_from_yaml_if_defined(
+ T & setting,
+ YAML::Node const & yaml, YamlNames const & ... names
+ ){
+ try{
+ detail::set_from_yaml_if_defined(setting, yaml, names...);
+ }
+ catch(invalid_type const & ex){
+ throw invalid_type{
+ "In option " + join(": ", names...) + ": " + ex.what()
+ };
+ }
+ catch(std::invalid_argument const & ex){
+ throw missing_option{
+ "In option " + join(": ", names...) + ":"
+ " invalid value " + ex.what()
+ };
+ }
+ }
+
}
diff --git a/include/RHEJ/utility.hh b/include/RHEJ/utility.hh
index 542e710..9caab71 100644
--- a/include/RHEJ/utility.hh
+++ b/include/RHEJ/utility.hh
@@ -1,118 +1,141 @@
/**
* \file utility.hh
* Author: Tuomas Hapola
* \brief Contains the struct Sparticle which contains particle information and parameters.
*
* Also contains some functions which are useful for comparison on particles parameters.
*/
#pragma once
#include <algorithm>
+#include <boost/core/demangle.hpp>
+
// FastJet Includes
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "RHEJ/PDG_codes.hh"
namespace RHEJ{
/** \struct Sparticle utility.hh "include/RHEJ/utility.hh"
* \brief The struct which contains all the parameters of a particle.
*
* Constituted by PiD and PseudoJet Objects.
*/
struct Sparticle {
ParticleID type;
fastjet::PseudoJet p;
//! get rapidity function
double rapidity() const{
return p.rapidity();
}
//! get perp function
double perp() const{
return p.perp();
}
//! get Px function
double px() const{
return p.px();
}
//! get Py function
double py() const{
return p.py();
}
//! Get Pz function
double pz() const{
return p.pz();
}
//! Get P0 function
double E() const{
return p.E();
}
};
/** \struct rapidity_less utility.hh "include/RHEJ/utility.hh
- * \brief A struct which allows quick comparison of two different jets rapidities.
+ * \brief A struct which allows quick comparison of two different jets rapidities.
*/
struct rapidity_less{
template<class FourVector>
bool operator()(FourVector const & p1, FourVector const & p2){
return p1.rapidity() < p2.rapidity();
}
};
-
+
/** \struct pz_less utility.hh "include/RHEJ/utility.hh
- * \brief A struct which allows quick comparison of Pz between two jets.
+ * \brief A struct which allows quick comparison of Pz between two jets.
*/
struct pz_less{
template<class FourVector>
bool operator()(FourVector const & p1, FourVector const & p2){
return p1.pz() < p2.pz();
}
};
-
+
inline
std::vector<fastjet::PseudoJet> to_PseudoJet(
std::vector<Sparticle> const & v
){
std::vector<fastjet::PseudoJet> result;
for(auto && sp: v) result.emplace_back(sp.p);
return result;
}
inline
bool is_parton(Sparticle const & p){
return is_parton(p.type);
}
inline bool is_AWZH_boson(Sparticle const & particle){
return is_AWZH_boson(particle.type);
}
inline
std::vector<Sparticle> filter_partons(
std::vector<Sparticle> const & v
){
std::vector<Sparticle> result;
result.reserve(v.size());
std::copy_if(
begin(v), end(v), std::back_inserter(result),
[](Sparticle const & p){ return is_parton(p); }
);
return result;
}
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... a){
return std::unique_ptr<T>{new T{std::forward<Args>(a)...}};
}
template<typename T, typename... U>
constexpr
std::array<T, 1 + sizeof...(U)> make_array(T t, U&&... rest){
return {{t, std::forward<U>(rest)...}};
}
+ inline
+ std::string join(
+ std::string const & /* delim */, std::string const & str
+ ){
+ return str;
+ }
+
+ template<typename... Strings>
+ std::string join(
+ std::string const & delim,
+ std::string const & first, std::string const & second,
+ Strings&&... rest
+ ){
+ return join(delim, first + delim + second, std::forward<Strings>(rest)...);
+ }
+
+ template<typename T>
+ std::string type_string(T&&){
+ return boost::core::demangle(typeid(T).name());
+ }
+
}
diff --git a/src/config.cc b/src/config.cc
index e7e9f5e..a5851ce 100644
--- a/src/config.cc
+++ b/src/config.cc
@@ -1,606 +1,412 @@
#include "RHEJ/config.hh"
#include "RHEJ/exceptions.hh"
#include <set>
#include <string>
#include <vector>
#include <iostream>
#include <stdexcept>
namespace RHEJ{
+
+ namespace{
+ fastjet::JetAlgorithm to_JetAlgorithm(std::string const & algo){
+ using namespace fastjet;
+ static const std::map<std::string, fastjet::JetAlgorithm> known = {
+ {"kt", kt_algorithm},
+ {"cambridge", cambridge_algorithm},
+ {"antikt", antikt_algorithm},
+ {"genkt", genkt_algorithm},
+ {"cambridge for passive", cambridge_for_passive_algorithm},
+ {"genkt for passive", genkt_for_passive_algorithm},
+ {"ee kt", ee_kt_algorithm},
+ {"ee genkt", ee_genkt_algorithm},
+ {"plugin", plugin_algorithm}
+ };
+ const auto res = known.find(algo);
+ if(res == known.end()){
+ throw std::invalid_argument("Unknown jet algorithm " + algo);
+ }
+ return res->second;
+ }
+
+ EventTreatment to_EventTreatment(std::string const & name){
+ static const std::map<std::string, EventTreatment> known = {
+ {"reweight", EventTreatment::reweight},
+ {"keep", EventTreatment::keep},
+ {"discard", EventTreatment::discard}
+ };
+ const auto res = known.find(name);
+ if(res == known.end()){
+ throw std::invalid_argument("Unknown event treatment " + name);
+ }
+ return res->second;
+ }
+
+ }
+
+ namespace detail{
+ void set_from_yaml(fastjet::JetAlgorithm & setting, YAML::Node const & yaml){
+ setting = to_JetAlgorithm(yaml.as<std::string>());
+ }
+
+ void set_from_yaml(EventTreatment & setting, YAML::Node const & yaml){
+ setting = to_EventTreatment(yaml.as<std::string>());
+ }
+ }
+
+ namespace{
+ JetParameters get_jet_parameters(
+ YAML::Node const & node,
+ std::string const & entry
+ ){
+ assert(node);
+ JetParameters result;
+ fastjet::JetAlgorithm jet_algo = fastjet::antikt_algorithm;
+ double R;
+ set_from_yaml_if_defined(jet_algo, node, entry, "algorithm");
+ set_from_yaml(R, node, entry, "R");
+ result.def = fastjet::JetDefinition{jet_algo, R};
+ set_from_yaml(result.min_pt, node, entry, "min pt");
+ return result;
+ }
+
+ HiggsCouplingSettings get_Higgs_coupling(
+ YAML::Node const & node,
+ std::string const & entry
+ ){
+ assert(node);
+ static constexpr double mt_max = 2e4;
+#ifndef RHEJ_BUILD_WITH_QCDLOOP
+ if(node[entry]){
+ throw std::invalid_argument{
+ "Higgs coupling settings require building Reversed HEJ "
+ "with QCDloop support"
+ };
+ }
+#endif
+ HiggsCouplingSettings settings;
+ set_from_yaml_if_defined(settings.mt, node, entry, "mt");
+ set_from_yaml_if_defined(settings.mb, node, entry, "mb");
+ set_from_yaml_if_defined(settings.include_bottom, node, entry, "include bottom");
+ set_from_yaml_if_defined(settings.use_impact_factors, node, entry, "use impact factors");
+ if(settings.use_impact_factors){
+ if(settings.mt != std::numeric_limits<double>::infinity()){
+ throw std::invalid_argument{
+ "Conflicting settings: "
+ "impact factors may only be used in the infinite top mass limit"
+ };
+ }
+ }
+ else{
+ // huge values of the top mass are numerically unstable
+ settings.mt = std::min(settings.mt, mt_max);
+ }
+ return settings;
+ }
+ }
+
FileFormat to_FileFormat(std::string const & name){
static const std::map<std::string, FileFormat> known = {
{"Les Houches", FileFormat::Les_Houches},
{"HepMC", FileFormat::HepMC}
};
const auto res = known.find(name);
if(res == known.end()){
throw std::invalid_argument("Unknown file format " + name);
}
return res->second;
}
std::string extract_suffix(std::string const & filename){
size_t separator = filename.rfind('.');
if(separator == filename.npos) return {};
return filename.substr(separator + 1);
}
FileFormat format_from_suffix(std::string const & filename){
const std::string suffix = extract_suffix(filename);
if(suffix == "lhe") return FileFormat::Les_Houches;
if(suffix == "hepmc3") return FileFormat::HepMC;
throw std::invalid_argument{
"Can't determine format for output file " + filename
};
}
}
namespace YAML {
std::string to_string(NodeType::value type){
switch (type) {
case NodeType::Null: return "Null";
case NodeType::Scalar: return "Scalar";
case NodeType::Sequence: return "Sequence";
case NodeType::Map: return "Map";
case NodeType::Undefined: return "Undefined";
default:
throw std::logic_error{"Missing case in switch statement"};
}
}
template<>
struct convert<RHEJ::OutputFile> {
static Node encode(RHEJ::OutputFile const & outfile) {
Node node;
node[to_string(outfile.format)] = outfile.name;
return node;
}
static bool decode(Node const & node, RHEJ::OutputFile & out) {
switch(node.Type()){
case NodeType::Map: {
YAML::const_iterator it = node.begin();
out.format = RHEJ::to_FileFormat(it->first.as<std::string>());
out.name = it->second.as<std::string>();
return true;
}
case NodeType::Scalar:
out.name = node.as<std::string>();
out.format = RHEJ::format_from_suffix(out.name);
return true;
default:
return false;
}
}
};
}
namespace RHEJ{
namespace{
static const std::set<std::string> known = {
{"trials"},
{"min extparton pt"}, {"max ext soft pt fraction"},
{"resummation jets"}, {"fixed order jets"},
{"FKL"}, {"non-FKL"}, {"unordered"},
{"log correction"},
{"event output"},
{"analysis"},
{"unweight"}, {"RanLux init"},
{"scales"}, {"scale factors"}, {"max scale ratio"},
{"Higgs coupling"}
};
static const std::set<std::string> known_jet = {
{"min pt"}, {"algorithm"}, {"R"}
};
- template<typename T>
- std::string type_string();
-
- template<>
- std::string type_string<std::vector<double>>(){
- return "array of doubles";
- }
-
- template<>
- std::string type_string<std::vector<std::string>>(){
- return "array of strings";
- }
-
- template<>
- std::string type_string<int>(){
- return "integer";
- }
-
- template<>
- std::string type_string<double>(){
- return "double";
- }
-
- template<>
- std::string type_string<bool>(){
- return "bool";
- }
-
- template<>
- std::string type_string<std::string>(){
- return "string";
- }
-
- template<>
- std::string type_string<std::vector<OutputFile>>(){
- return "array of output files";
- }
-
- fastjet::JetAlgorithm to_JetAlgorithm(std::string const & algo){
- using namespace fastjet;
- static const std::map<std::string, fastjet::JetAlgorithm> known = {
- {"kt", kt_algorithm},
- {"cambridge", cambridge_algorithm},
- {"antikt", antikt_algorithm},
- {"genkt", genkt_algorithm},
- {"cambridge for passive", cambridge_for_passive_algorithm},
- {"genkt for passive", genkt_for_passive_algorithm},
- {"ee kt", ee_kt_algorithm},
- {"ee genkt", ee_genkt_algorithm},
- {"plugin", plugin_algorithm}
- };
- const auto res = known.find(algo);
- if(res == known.end()){
- throw std::invalid_argument("Unknown jet algorithm " + algo);
- }
- return res->second;
- }
-
- EventTreatment to_EventTreatment(std::string const & name){
- static const std::map<std::string, EventTreatment> known = {
- {"reweight", EventTreatment::reweight},
- {"keep", EventTreatment::keep},
- {"discard", EventTreatment::discard}
- };
- const auto res = known.find(name);
- if(res == known.end()){
- throw std::invalid_argument("Unknown event treatment " + name);
- }
- return res->second;
- }
-
- // helper struct to allow partial template specialisation
- template<typename T>
- struct existing_as_helper{
-
- static T as(YAML::Node const & config, std::string const & entry){
- assert(config[entry]);
- try{
- return config[entry].as<T>();
- }
- catch(std::exception const &){
- throw invalid_type{
- "Entry " + entry + " is not of type " + type_string<T>()
- };
- }
- }
-
- };
-
- template<>
- struct existing_as_helper<fastjet::JetAlgorithm>{
-
- static fastjet::JetAlgorithm as(
- YAML::Node const & config, std::string const & entry
- ){
- assert(config[entry]);
- const std::string algo_name =
- existing_as_helper<std::string>::as(config, entry);
- return to_JetAlgorithm(algo_name);
- }
-
- };
-
- template<>
- struct existing_as_helper<EventTreatment>{
-
- static EventTreatment as(
- YAML::Node const & config, std::string const & entry
- ){
- assert(config[entry]);
- const std::string name =
- existing_as_helper<std::string>::as(config, entry);
- return to_EventTreatment(name);
- }
-
- };
-
- template<>
- struct existing_as_helper<OutputFile>{
-
- static OutputFile as(
- YAML::Node const & config, std::string const & entry
- ){
- assert(config[entry]);
- YAML::convert<RHEJ::OutputFile> converter{};
- OutputFile out;
- if(converter.decode(config[entry], out)) return out;
- throw std::invalid_argument{
- "Bad output file setting: " + config[entry].as<std::string>()
- };
- }
- };
-
- template<typename T>
- struct existing_as_helper<std::vector<T>>{
-
- static std::vector<T> as(
- YAML::Node const & config, std::string const & entry
- ){
- assert(config[entry]);
- // special case: treat a single value like a vector with one element
- if(config[entry].IsScalar()){
- return {existing_as_helper<T>::as(config, entry)};
- }
- try{
- return config[entry].as<std::vector<T>>();
- }
- catch(std::exception const & p){
- std::cerr << "Error: " << p.what() << '\n';
- throw invalid_type{
- "Entry " + entry + " is not of type " + type_string<std::vector<T>>()
- };
- }
- }
-
- };
-
- template<typename T>
- T existing_as(YAML::Node const & config, std::string const & entry){
- return existing_as_helper<T>::as(config, entry);
- }
-
- template<typename T>
- T as(YAML::Node const & config, std::string const & entry);
-
- template<>
- JetParameters existing_as<JetParameters>(
- YAML::Node const & config, std::string const & entry
- ){
- assert(config[entry]);
- YAML::Node const & jet_config = config[entry];
- JetParameters result;
- for(auto const & opt: jet_config){
- auto const & opt_name = opt.first.as<std::string>();
- if(! known_jet.count(opt_name)){
- throw unknown_option{"Unknown option " + opt_name};
- }
- }
- try{
- result.def = fastjet::JetDefinition{
- as<fastjet::JetAlgorithm>(jet_config, "algorithm"),
- as<double>(jet_config, "R")
- };
- result.min_pt = as<double>(jet_config, "min pt");
- return result;
- }
- catch(missing_option const & exc){
- throw missing_option{"In entry " + entry + ":\n" + exc.what()};
- }
- catch(invalid_type const & exc){
- throw invalid_type{"In entry " + entry + ":\n" + exc.what()};
- }
- }
-
- template<typename T>
- T as(YAML::Node const & config, std::string const & entry){
- if(!config[entry]){
- throw missing_option{"No entry for option " + entry};
- }
- return existing_as<T>(config, entry);
- }
-
- template<typename T>
- optional<T> as_optional(YAML::Node const & config, std::string const & entry){
- if(!config[entry]) return {};
- return {existing_as<T>(config, entry)};
- }
-
- template<>
- HiggsCouplingSettings as<HiggsCouplingSettings>(
- YAML::Node const & config, std::string const & entry
- ){
- static constexpr double mt_max = 2e4;
- HiggsCouplingSettings settings;
- if(!config[entry]) return settings;
-#ifndef RHEJ_BUILD_WITH_QCDLOOP
- throw std::invalid_argument{
- "Higgs coupling settings require building Reversed HEJ "
- "with QCDloop support"
- };
-#endif
- YAML::Node const & node = config[entry];
- if(!node.IsMap()){
- throw std::invalid_argument{
- "entry '" + entry + "' is a " + to_string(node.Type())
- + ", not a Map of properties"
- };
- }
- for(auto const & property: node){
- const auto key = property.first.as<std::string>();
- auto const & value = property.second;
- if(key == "mt") settings.mt = value.as<double>();
- else if(key == "mb") settings.mb = value.as<double>();
- else if(key == "include bottom"){
- settings.include_bottom = value.as<bool>();
- }
- else if(key == "use impact factors"){
- settings.use_impact_factors = value.as<bool>();
- }
- else{
- throw unknown_option{"Unknown option '" + key + "'"};
- }
- }
- if(settings.use_impact_factors){
- if(settings.mt != std::numeric_limits<double>::infinity()){
- throw std::invalid_argument{
- "Conflicting settings: "
- "impact factors may only be used in the infinite top mass limit"
- };
- }
- }
- else{
- // huge values of the top mass are numerically unstable
- settings.mt = std::min(settings.mt, mt_max);
- }
- return settings;
- }
-
void update_fixed_order_jet_parameters(
JetParameters & fixed_order_jets, YAML::Node const & yaml
){
- YAML::Node const & yaml_jets = yaml["fixed order jets"];
- assert(yaml_jets);
- for(auto const & opt: yaml_jets){
- auto const & opt_name = opt.first.as<std::string>();
- if(! known_jet.count(opt_name)){
- throw unknown_option{"Unknown option '" + opt_name + "'"};
- }
- }
- try{
- auto algo = as_optional<fastjet::JetAlgorithm>(yaml_jets, "algorithm");
- if(algo){
- fixed_order_jets.def = fastjet::JetDefinition{
- *algo, fixed_order_jets.def.R()
- };
- }
- auto R = as_optional<double>(yaml_jets, "R");
- if(R){
- fixed_order_jets.def = fastjet::JetDefinition{
- fixed_order_jets.def.jet_algorithm(), *R
- };
- }
- auto min_pt = as_optional<double>(yaml_jets, "min pt");
- if(min_pt) fixed_order_jets.min_pt = *min_pt;
- }
- catch(missing_option const & exc){
- throw missing_option{
- std::string{"In entry fixed order jets:\n"} + exc.what()
- };
- }
- catch(invalid_type const & exc){
- throw invalid_type{
- std::string{"In entry fixed order jets:\n"} + exc.what()
- };
- }
+ if(!yaml["fixed order jets"]) return;
+ set_from_yaml_if_defined(
+ fixed_order_jets.min_pt, yaml, "fixed order jets", "min pt"
+ );
+ fastjet::JetAlgorithm algo = fixed_order_jets.def.jet_algorithm();
+ set_from_yaml_if_defined(algo, yaml, "fixed order jets", "algorithm");
+ double R = fixed_order_jets.def.R();
+ set_from_yaml_if_defined(R, yaml, "fixed order jets", "R");
+ fixed_order_jets.def = fastjet::JetDefinition{algo, R};
}
// like std::stod, but throw if not the whole string can be converted
double to_double(std::string const & str){
std::size_t pos;
const double result = std::stod(str, &pos);
if(pos < str.size()){
throw std::invalid_argument(str + " is not a valid double value");
}
return result;
}
// simple (as in non-composite) scale functions
/**
* An example for a simple scale function would be Ht,
* Ht/2 is then composite (take Ht and then divide by 2)
*/
std::unique_ptr<ScaleFunction> make_simple_ScaleFunction_ptr(
std::string const & scale_fun
){
using ret_type = std::unique_ptr<ScaleFunction>;
assert(
scale_fun.empty() ||
(!std::isspace(scale_fun.front()) && !std::isspace(scale_fun.back()))
);
if(scale_fun == "input") return ret_type{new InputScales{}};
if(scale_fun == "Ht") return ret_type{new Ht{}};
if(scale_fun == "max jet pperp") return ret_type{new MaxJetPperp{}};
if(scale_fun == "jet invariant mass"){
return ret_type{new JetInvariantMass{}};
}
try{
const double scale = to_double(scale_fun);
return ret_type{new FixedScale{scale}};
} catch(std::invalid_argument const &){}
throw std::invalid_argument{"Unknown scale choice: " + scale_fun};
}
std::string trim_front(std::string const & str){
const auto new_begin = std::find_if(
begin(str), end(str), [](char c){ return ! std::isspace(c); }
);
return std::string(new_begin, end(str));
}
std::string trim_back(std::string str){
size_t pos = str.size() - 1;
// use guaranteed wrap-around behaviour to check whether we have
// traversed the whole string
for(; pos < str.size() && std::isspace(str[pos]); --pos) {}
str.resize(pos + 1); // note that pos + 1 can be 0
return str;
}
std::unique_ptr<ScaleFunction> make_ScaleFunction_ptr(
std::string const & scale_fun
){
assert(
scale_fun.empty() ||
(!std::isspace(scale_fun.front()) && !std::isspace(scale_fun.back()))
);
const size_t delim = scale_fun.find_first_of("*/");
if(delim == scale_fun.npos){
return make_simple_ScaleFunction_ptr(scale_fun);
}
const std::string first = trim_back(std::string{scale_fun, 0, delim});
const std::string second = trim_front(std::string{scale_fun, delim+1});
double factor;
std::unique_ptr<ScaleFunction> fun;
if(scale_fun[delim] == '/'){
factor = 1/to_double(second);
fun = make_simple_ScaleFunction_ptr(first);
}
else{
assert(scale_fun[delim] == '*');
try{
factor = to_double(second);
fun = make_simple_ScaleFunction_ptr(first);
}
catch(std::invalid_argument const &){
factor = to_double(first);
fun = make_simple_ScaleFunction_ptr(second);
}
}
assert(fun != nullptr);
return std::unique_ptr<ScaleFunction>{
new Product{factor, std::move(fun)}
};
}
ScaleConfig to_ScaleConfig(YAML::Node const & yaml){
ScaleConfig config;
- const auto scales = as<std::vector<std::string>>(yaml, "scales");
+ std::vector<std::string> scales;
+ set_from_yaml(scales, yaml, "scales");
config.scales.reserve(scales.size());
std::transform(
begin(scales), end(scales), std::back_inserter(config.scales),
make_ScaleFunction_ptr
);
- auto scale_factors = as_optional<std::vector<double>>(
- yaml, "scale factors"
- );
- if(scale_factors) config.scale_factors = std::move(*scale_factors);
- const auto max_scale_ratio = as_optional<double>(yaml, "max scale ratio");
- static_assert(
- std::numeric_limits<double>::has_infinity, "infinity not supported"
- );
- config.max_scale_ratio = max_scale_ratio?
- *max_scale_ratio:
- std::numeric_limits<double>::infinity()
- ;
+ set_from_yaml_if_defined(config.scale_factors, yaml, "scale factors");
+ config.max_scale_ratio = std::numeric_limits<double>::infinity();
+ set_from_yaml_if_defined(config.max_scale_ratio, yaml, "max scale ratio");
return config;
}
EventTreatMap get_event_treatment(
YAML::Node const & yaml
){
using namespace event_class;
EventTreatMap treat {
{no_2_jets, EventTreatment::discard},
- {bad_final_state, EventTreatment::discard}
+ {bad_final_state, EventTreatment::discard},
+ {FKL, EventTreatment::reweight},
+ {unob, EventTreatment::keep},
+ {unof, EventTreatment::keep},
+ {nonFKL, EventTreatment::keep}
};
- treat.emplace(FKL, as<EventTreatment>(yaml, "FKL"));
- const auto unordered_treatment = as<EventTreatment>(yaml, "unordered");
- treat.emplace(unordered_forward, unordered_treatment);
- treat.emplace(unordered_backward, unordered_treatment);
- treat.emplace(nonFKL, as<EventTreatment>(yaml, "non-FKL"));
+ set_from_yaml(treat.at(FKL), yaml, "FKL");
+ set_from_yaml(treat.at(unob), yaml, "unordered");
+ treat.at(unof) = treat.at(unob);
+ set_from_yaml(treat.at(nonFKL), yaml, "non-FKL");
if(treat[nonFKL] == EventTreatment::reweight){
throw std::invalid_argument{"Cannot reweight non-FKL events"};
}
return treat;
}
Config to_Config(YAML::Node const & yaml){
for(auto const & opt: yaml){
auto const & opt_name = opt.first.as<std::string>();
if(! known.count(opt_name)){
throw unknown_option{"Unknown option '" + opt_name + "'"};
}
}
Config config;
- config.resummation_jets = as<JetParameters>(yaml, "resummation jets");
+ config.resummation_jets = get_jet_parameters(yaml, "resummation jets");
config.fixed_order_jets = config.resummation_jets;
- if(yaml["fixed order jets"]){
- update_fixed_order_jet_parameters(config.fixed_order_jets, yaml);
- }
- config.min_extparton_pt = as<double>(yaml, "min extparton pt");
- config.max_ext_soft_pt_fraction = yaml["max ext soft pt fraction"]?
- as<double>(yaml, "max ext soft pt fraction"):
- std::numeric_limits<double>::infinity()
- ;
- config.trials = as<int>(yaml, "trials");
- config.log_correction = as<bool>(yaml, "log correction");
- config.unweight = as<bool>(yaml, "unweight");
+ update_fixed_order_jet_parameters(config.fixed_order_jets, yaml);
+ set_from_yaml(config.min_extparton_pt, yaml, "min extparton pt");
+ config.max_ext_soft_pt_fraction = std::numeric_limits<double>::infinity();
+ set_from_yaml_if_defined(
+ config.max_ext_soft_pt_fraction, yaml, "max ext soft pt fraction"
+ );
+ set_from_yaml(config.trials, yaml, "trials");
+ set_from_yaml(config.log_correction, yaml, "log correction");
+ set_from_yaml(config.unweight, yaml, "unweight");
config.treat = get_event_treatment(yaml);
- if(yaml["event output"]){
- config.output = as<std::vector<OutputFile>>(yaml, "event output");
- }
- config.RanLux_init = as_optional<std::string>(yaml, "RanLux init");
- config.analysis_parameters = yaml["analysis"]?yaml["analysis"]:YAML::Node{};
+ set_from_yaml_if_defined(config.output, yaml, "event output");
+ set_from_yaml_if_defined(config.RanLux_init, yaml, "RanLux init");
+ set_from_yaml_if_defined(config.analysis_parameters, yaml, "analysis");
config.scale_gen = ScaleGenerator{to_ScaleConfig(yaml)};
- config.Higgs_coupling = as<HiggsCouplingSettings>(yaml, "Higgs coupling");
+ config.Higgs_coupling = get_Higgs_coupling(yaml, "Higgs coupling");
return config;
}
} // anonymous namespace
Config load_config(std::string const & config_file){
try{
return to_Config(YAML::LoadFile(config_file));
}
catch(...){
std::cerr << "Error reading " << config_file << ":\n ";
throw;
}
}
Event ScaleGenerator::operator()(Event ev) const{
assert(ev.variations().empty());
assert(! settings_.scales.empty());
auto const & scales = settings_.scales;
auto const & scale_factors = settings_.scale_factors;
const double max_scale_ratio = settings_.max_scale_ratio;
// check if we are doing scale variation at all
if(scales.size() == 1 && scale_factors.empty()){
ev.central() = (*scales.front())(ev);
return ev;
}
for(auto && base_scale: scales){
const EventParameters cur_base = (*base_scale)(ev);
ev.variations().emplace_back(cur_base);
//multiplicative scale variation
for(double mur_factor: scale_factors){
const double mur = cur_base.mur*mur_factor;
for(double muf_factor: scale_factors){
if(muf_factor == 1. && mur_factor == 1.) continue;
const double muf = cur_base.muf*muf_factor;
if(mur/muf < 1/max_scale_ratio || mur/muf > max_scale_ratio) continue;
ev.variations().emplace_back(
EventParameters{mur, muf, cur_base.weight}
);
}
}
};
ev.central() = (*scales.front())(ev);
return ev;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jan 21, 2:18 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4243641
Default Alt Text
(37 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment