Page MenuHomeHEPForge

No OneTemporary

diff --git a/src/RivetAnalysis.cc b/src/RivetAnalysis.cc
index c85515f..7db9b8b 100644
--- a/src/RivetAnalysis.cc
+++ b/src/RivetAnalysis.cc
@@ -1,119 +1,143 @@
/**
* \authors Jeppe Andersen, Tuomas Hapola, Marian Heil, Andreas Maier, Jennifer Smillie
* \date 2019
* \copyright GPLv2 or later
*/
#include "HEJ/RivetAnalysis.hh"
#ifdef HEJ_BUILD_WITH_RIVET
#include <ostream>
#include <stddef.h>
#include "yaml-cpp/yaml.h"
#include "Rivet/AnalysisHandler.hh"
#include "HepMC/GenEvent.h"
#include "HEJ/Event.hh"
#include "HEJ/exceptions.hh"
#endif
namespace HEJ{
std::unique_ptr<Analysis> RivetAnalysis::create(YAML::Node const & config){
return std::unique_ptr<Analysis>{new RivetAnalysis{config}};
}
}
#ifdef HEJ_BUILD_WITH_RIVET
namespace HEJ {
RivetAnalysis::RivetAnalysis(YAML::Node const & config):
output_name_{config["output"].as<std::string>()},
first_event_(true)
{
// read in analyses
const auto & name_node = config["rivet"];
switch(name_node.Type()){
case YAML::NodeType::Scalar:
analyses_names_.push_back(name_node.as<std::string>());
break;
case YAML::NodeType::Sequence:
for(YAML::const_iterator it = name_node.begin(); it != name_node.end(); ++it){
analyses_names_.push_back(it->as<std::string>());
}
break;
default:
throw std::invalid_argument{
"No Analysis was provided to rivet. "
"Either give an analysis or deactivate rivet."
};
}
}
+ namespace {
+ void replace(
+ std::string & str,
+ char to_replace, std::string const & replacement
+ ) {
+ for(
+ auto pos = str.find(to_replace);
+ pos != str.npos;
+ pos = str.find(to_replace, pos)
+ ) {
+ str.replace(pos, 1, replacement);
+ pos += replacement.size();
+ }
+ }
+
+ // remove "special" characters from scale name
+ // so that we can more easily use it as part of a file name
+ std::string sanitise_scalename(std::string scalename) {
+ replace(scalename, '/', "_over_");
+ replace(scalename, '*', "_times_");
+ return scalename;
+ }
+ }
+
void RivetAnalysis::init(Event const & event){
rivet_runs_.push_back(
{std::make_unique<Rivet::AnalysisHandler>(), "", HepMCInterface()}
);
rivet_runs_.back().handler->addAnalyses(analyses_names_);
if( !event.variations().empty() ){
rivet_runs_.reserve(event.variations().size()+1);
for(auto const & vari : event.variations()){
std::ostringstream name;
- name << ".Scale" << vari.description->scale_name
+ name << ".Scale" << sanitise_scalename(vari.description->scale_name)
<< "_MuR" << vari.description->mur_factor
<< "_MuF" << vari.description->muf_factor;
rivet_runs_.push_back(
{std::make_unique<Rivet::AnalysisHandler>(), name.str(), HepMCInterface()}
);
rivet_runs_.back().handler->addAnalyses(analyses_names_);
}
}
}
void RivetAnalysis::fill(Event const & event, Event const &){
if(first_event_){
first_event_=false;
init(event);
}
HepMC::GenEvent hepmc_kin(rivet_runs_[0].hepmc.init_kinematics(event));
for(size_t i = 0; i < rivet_runs_.size(); ++i){
auto & run = rivet_runs_[i];
run.hepmc.set_central(hepmc_kin, event, i-1); // -1: first = central
run.handler->analyze(hepmc_kin);
}
}
void RivetAnalysis::finalise(){
for(auto const & run: rivet_runs_){
run.handler->finalize();
run.handler->writeData(output_name_+run.name+std::string(".yoda"));
}
}
} // namespace HEJ
#else // no rivet => create empty analysis
namespace Rivet {
class AnalysisHandler {};
}
namespace HEJ {
RivetAnalysis::RivetAnalysis(YAML::Node const &)
{
throw std::invalid_argument(
"Failed to create RivetAnalysis: "
"HEJ 2 was built without rivet support"
);
}
void RivetAnalysis::init(Event const &){}
void RivetAnalysis::fill(Event const &, Event const &){}
void RivetAnalysis::finalise(){}
} // namespace HEJ
#endif
diff --git a/src/ScaleFunction.cc b/src/ScaleFunction.cc
index 5747f97..67a8e99 100644
--- a/src/ScaleFunction.cc
+++ b/src/ScaleFunction.cc
@@ -1,149 +1,149 @@
/**
* \authors Jeppe Andersen, Tuomas Hapola, Marian Heil, Andreas Maier, Jennifer Smillie
* \date 2019
* \copyright GPLv2 or later
*/
#include "HEJ/ScaleFunction.hh"
#include <cassert>
#include "HEJ/Event.hh"
#include "HEJ/exceptions.hh"
namespace HEJ{
double H_T(Event const & ev){
double result = 0.;
for(size_t i = 0; i < ev.outgoing().size(); ++i){
auto const decay_products = ev.decays().find(i);
if(decay_products == end(ev.decays())){
result += ev.outgoing()[i].perp();
}
else{
for(auto const & particle: decay_products->second){
result += particle.perp();
}
}
}
return result;
}
double max_jet_pt(Event const & ev) {
return sorted_by_pt(ev.jets()).front().pt();
}
double jet_invariant_mass(Event const & ev) {
fastjet::PseudoJet sum;
for(const auto & jet: ev.jets()) sum+=jet;
return sum.m();
}
double m_j1j2(Event const & ev) {
const auto jets = sorted_by_pt(ev.jets());
assert(jets.size() >= 2);
return (jets[0] + jets[1]).m();
}
ScaleFunction operator*(double factor, ScaleFunction base_scale) {
- base_scale.name_.insert(0, std::to_string(factor) + "_times_");
+ base_scale.name_.insert(0, std::to_string(factor) + '*');
auto new_fun =
[factor,fun{std::move(base_scale.fun_)}](HEJ::Event const & ev) {
return factor*fun(ev);
};
base_scale.fun_ = std::move(new_fun);
return base_scale;
}
ScaleFunction operator/(ScaleFunction base_scale, double denom) {
- base_scale.name_.append("_over_" + std::to_string(denom));
+ base_scale.name_.append('/' + std::to_string(denom));
auto new_fun =
[denom,fun{std::move(base_scale.fun_)}](HEJ::Event const & ev) {
return fun(ev)/denom;
};
base_scale.fun_ = std::move(new_fun);
return base_scale;
}
// TODO: significant logic duplication with operator()
void ScaleGenerator::gen_descriptions() {
if(scales_.empty()) {
throw std::logic_error{"Need at least one scale"};
}
descriptions_.emplace_back(
std::make_shared<ParameterDescription>(scales_.front().name(), 1., 1.)
);
for(auto & base_scale: scales_){
const auto base_name = base_scale.name();
descriptions_.emplace_back(
std::make_shared<ParameterDescription>(base_name, 1., 1.)
);
//multiplicative scale variation
for(double mur_factor: scale_factors_){
for(double muf_factor: scale_factors_){
if(muf_factor == 1. && mur_factor == 1.) continue;
if(
mur_factor/muf_factor < 1/max_scale_ratio_
|| mur_factor/muf_factor > max_scale_ratio_
) continue;
descriptions_.emplace_back(
std::make_shared<ParameterDescription>(
base_name, mur_factor, muf_factor
)
);
}
}
}
}
Event ScaleGenerator::operator()(Event ev) const {
if(! ev.variations().empty()) {
throw std::invalid_argument{"Input event already has scale variation"};
}
assert(!scales_.empty());
assert(!descriptions_.empty());
size_t descr_idx = 0;
const double mu_central = (scales_.front())(ev);
ev.central().mur = mu_central;
ev.central().muf = mu_central;
assert(descr_idx < descriptions_.size());
assert(descriptions_[descr_idx]);
ev.central().description = descriptions_[descr_idx++];
// check if we are doing scale variation at all
if(scales_.size() == 1 && scale_factors_.empty()) return ev;
for(auto & base_scale: scales_){
const double mu_base = base_scale(ev);
assert(descr_idx < descriptions_.size());
assert(descriptions_[descr_idx]);
ev.variations().emplace_back(
EventParameters{
mu_base, mu_base, ev.central().weight, descriptions_[descr_idx++]
}
);
//multiplicative scale variation
for(double mur_factor: scale_factors_){
const double mur = mu_base*mur_factor;
for(double muf_factor: scale_factors_){
if(muf_factor == 1. && mur_factor == 1.) continue;
const double muf = mu_base*muf_factor;
if(
mur/muf < 1/max_scale_ratio_
|| mur/muf > max_scale_ratio_
) continue;
assert(descr_idx < descriptions_.size());
assert(descriptions_[descr_idx]);
ev.variations().emplace_back(
EventParameters{
mur, muf, ev.central().weight, descriptions_[descr_idx++]
}
);
}
}
};
return ev;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jan 20, 11:01 PM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4242779
Default Alt Text
(8 KB)

Event Timeline