Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8723442
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Subscribers
None
View Options
diff --git a/FixedOrderGen/include/Unweighter.hh b/FixedOrderGen/include/Unweighter.hh
index f268f00..c392a8c 100644
--- a/FixedOrderGen/include/Unweighter.hh
+++ b/FixedOrderGen/include/Unweighter.hh
@@ -1,52 +1,72 @@
#pragma once
#include <limits>
#include <cmath>
#include "RHEJ/optional.hh"
#include "RHEJ/RNG.hh"
namespace RHEJ {
class Event;
}
namespace HEJFOG {
namespace detail {
+
+ bool has_jet_softer_than(RHEJ::Event const & ev, double pt);
+
template<typename Iterator>
- double calc_cut(Iterator begin, Iterator end, double max_dev) {
+ double calc_cut(
+ Iterator begin, Iterator end, double max_dev,
+ double min_pt
+ ) {
double mean = 0.;
double err = 0.;
double awt_sum = 0.;
for(; begin != end; ++begin){
+ if(has_jet_softer_than(*begin, min_pt)) continue;
const double awt = std::abs(begin->central().weight);
const double tmp = awt*std::log(awt);
mean += tmp;
err += tmp*tmp;
awt_sum += awt;
}
mean /= awt_sum;
err = std::sqrt(err)/awt_sum;
return std::exp(mean + max_dev*err);
}
}
class Unweighter {
public:
template<typename Iterator>
Unweighter(
Iterator begin, Iterator end, double max_dev,
- RHEJ::RNG & ran
+ RHEJ::RNG & ran,
+ /* minimum pt of jets for an event to be considered for unweighting
+ *
+ * If the 'jets: peak pt' option is set to the *resummation* jet
+ * threshold, events with softer jets will have a spurious
+ * large weight, although they hardly contribute after resummation.
+ * This destroys the unweighting efficiency.
+ * By setting min_unweight_pt to the same threshold, we can exclude
+ * these events from unweighting.
+ */
+ double min_unweight_pt = 0.
):
- cut_{detail::calc_cut(begin, end, max_dev)},
+ cut_{detail::calc_cut(begin, end, max_dev, min_unweight_pt)},
+ min_unweight_pt_{min_unweight_pt},
ran_{ran}
{}
RHEJ::optional<RHEJ::Event> unweight(RHEJ::Event ev) const;
private:
double cut_;
+ double min_unweight_pt_;
std::reference_wrapper<RHEJ::RNG> ran_;
+ std::function<bool(RHEJ::Event const &)> unweight_ok_;
};
}
diff --git a/FixedOrderGen/src/Unweighter.cc b/FixedOrderGen/src/Unweighter.cc
index d9e4da3..c0791e1 100644
--- a/FixedOrderGen/src/Unweighter.cc
+++ b/FixedOrderGen/src/Unweighter.cc
@@ -1,24 +1,34 @@
#include "Unweighter.hh"
-#include "RHEJ/Event.hh"
+#include <cassert>
+#include "RHEJ/Event.hh"
namespace HEJFOG {
+ namespace detail {
+ bool has_jet_softer_than(RHEJ::Event const & ev, double pt) {
+ assert(! ev.jets().empty());
+ const auto softest_jet = fastjet::sorted_by_pt(ev.jets()).back();
+ return softest_jet.pt() < pt;
+ }
+ }
+
namespace {
void normalise_weights(RHEJ::Event & ev, double target) {
const double awt = std::abs(ev.central().weight);
ev.central().weight *= target/awt;
for(auto & var: ev.variations()) var.weight *= target/awt;
}
}
RHEJ::optional<RHEJ::Event> Unweighter::unweight(RHEJ::Event ev) const {
+ if(detail::has_jet_softer_than(ev, min_unweight_pt_)) return ev;
const double awt = std::abs(ev.central().weight);
if(ran_.get().flat() < awt/cut_) {
if(awt < cut_) normalise_weights(ev, cut_);
return ev;
}
return {};
}
}
diff --git a/FixedOrderGen/src/main.cc b/FixedOrderGen/src/main.cc
index 64d5089..450b288 100644
--- a/FixedOrderGen/src/main.cc
+++ b/FixedOrderGen/src/main.cc
@@ -1,241 +1,242 @@
/**
* Name: main.cc
* Authors: Jeppe R. Andersen
*/
#include <fstream>
#include <algorithm>
#include <memory>
#include <chrono>
#include <iostream>
#include <map>
#include "yaml-cpp/yaml.h"
#include "config.hh"
#include "LHEF/LHEF.h"
#include "RHEJ/CombinedEventWriter.hh"
#include "RHEJ/get_analysis.hh"
#include "RHEJ/utility.hh"
//#include "RHEJ/EventReweighter.hh"
#include "RHEJ/stream.hh"
#include "RHEJ/LesHouchesWriter.hh"
#include "RHEJ/ProgressBar.hh"
#include "RHEJ/make_RNG.hh"
#include "EventGenerator.hh"
#include "PhaseSpacePoint.hh"
#include "Unweighter.hh"
#include "CrossSectionAccumulator.hh"
namespace{
constexpr auto banner =
" __ ___ __ ______ __ __ \n"
" / / / (_)___ _/ /_ / ____/___ ___ _________ ___ __ / /__ / /______ \n"
" / /_/ / / __ `/ __ \\ / __/ / __ \\/ _ \\/ ___/ __ `/ / / / __ / / _ \\/ __/ ___/ \n"
" / __ / / /_/ / / / / / /___/ / / / __/ / / /_/ / /_/ / / /_/ / __/ /_(__ ) \n"
" /_/ /_/_/\\__, /_/ /_/ /_____/_/ /_/\\___/_/ \\__, /\\__, / \\____/\\___/\\__/____/ \n"
" ____///__/ __ ____ ///__//____/ ______ __ \n"
" / ____(_) _____ ____/ / / __ \\_________/ /__ _____ / ____/__ ____ ___ _________ _/ /_____ _____\n"
" / /_ / / |/_/ _ \\/ __ / / / / / ___/ __ / _ \\/ ___/ / / __/ _ \\/ __ \\/ _ \\/ ___/ __ `/ __/ __ \\/ ___/\n"
" / __/ / /> </ __/ /_/ / / /_/ / / / /_/ / __/ / / /_/ / __/ / / / __/ / / /_/ / /_/ /_/ / / \n"
" /_/ /_/_/|_|\\___/\\__,_/ \\____/_/ \\__,_/\\___/_/ \\____/\\___/_/ /_/\\___/_/ \\__,_/\\__/\\____/_/ \n"
;
constexpr double invGeV2_to_pb = 389379292.;
constexpr long long max_warmup_events = 10000;
}
HEJFOG::Config load_config(char const * filename){
try{
return HEJFOG::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);
}
}
void rescale_weights(RHEJ::Event & ev, double factor) {
ev.central().weight *= factor;
for(auto & var: ev.variations()){
var.weight *= factor;
}
}
int main(int argn, char** argv) {
using namespace std::string_literals;
if (argn < 2) {
std::cerr << "\n# Usage:\n.FOgen config_file\n";
return EXIT_FAILURE;
}
std::cout << banner;
fastjet::ClusterSequence::print_banner();
using clock = std::chrono::system_clock;
const auto start_time = clock::now();
// read configuration
auto config = load_config(argv[1]);
std::unique_ptr<RHEJ::Analysis> analysis = get_analysis(
config.analysis_parameters
);
assert(analysis != nullptr);
auto ran = RHEJ::make_RNG(config.rng.name, config.rng.seed);
assert(ran != nullptr);
RHEJ::ScaleGenerator scale_gen{
config.scales.base,
config.scales.factors,
config.scales.max_ratio
};
HEJFOG::EventGenerator generator{
config.process,
config.beam,
std::move(scale_gen),
config.jets,
config.pdf_id,
config.unordered_fraction,
config.Higgs_properties,
config.Higgs_coupling,
*ran
};
//TODO: fix Les Houches init block (HEPRUP)
LHEF::HEPRUP lhefheprup;
lhefheprup.IDBMUP=std::pair<long,long>(config.beam.particles[0], config.beam.particles[1]);
lhefheprup.EBMUP=std::make_pair(config.beam.energy, config.beam.energy);
lhefheprup.PDFGUP=std::make_pair(0,0);
lhefheprup.PDFSUP=std::make_pair(config.pdf_id,config.pdf_id);
lhefheprup.NPRUP=1;
lhefheprup.XSECUP=std::vector<double>(1.);
lhefheprup.XERRUP=std::vector<double>(1.);
lhefheprup.LPRUP=std::vector<int>{1};
RHEJ::CombinedEventWriter writer{config.output, lhefheprup};
RHEJ::optional<HEJFOG::Unweighter> unweighter{};
std::map<HEJFOG::Status, int> status_counter;
std::vector<RHEJ::Event> events;
int trials = 0;
// warm-up phase to train unweighter
if(config.unweight) {
std::cout << "Calibrating unweighting ...\n";
const auto warmup_start = clock::now();
const size_t warmup_events = config.unweight->sample_size;
RHEJ::ProgressBar<size_t> warmup_progress{std::cout, warmup_events};
for(; events.size() < warmup_events; ++trials){
auto ev = generator.gen_event();
++status_counter[generator.status()];
if(generator.status() == HEJFOG::good && analysis->pass_cuts(ev, ev)) {
events.emplace_back(std::move(ev));
++warmup_progress;
}
}
std::cout << std::endl;
unweighter = HEJFOG::Unweighter{
- begin(events), end(events), config.unweight->max_dev, *ran
+ begin(events), end(events), config.unweight->max_dev, *ran,
+ config.jets.peak_pt?(*config.jets.peak_pt):0.
};
std::vector<RHEJ::Event> unweighted_events;
for(auto && ev: events) {
auto unweighted = unweighter->unweight(std::move(ev));
if(unweighted) {
unweighted_events.emplace_back(std::move(*unweighted));
}
}
events = std::move(unweighted_events);
if(events.empty()) {
std::cerr <<
"Failed to generate events. Please increase \"unweight: sample size\""
" or reduce \"unweight: max deviation\"\n";
return EXIT_FAILURE;
}
const auto warmup_end = clock::now();
const double completion = static_cast<double>(events.size())/config.events;
const std::chrono::duration<double> remaining_time =
(warmup_end- warmup_start)*(1./completion - 1);
const auto finish = clock::to_time_t(
std::chrono::time_point_cast<std::chrono::seconds>(warmup_end + remaining_time)
);
std::cout
<< "Generated " << events.size() << "/" << config.events << " events ("
<< static_cast<int>(std::round(100*completion)) << "%)\n"
<< "Estimated remaining generation time: "
<< remaining_time.count() << " seconds ("
<< std::put_time(std::localtime(&finish), "%c") << ")\n\n";
}
RHEJ::ProgressBar<long long> progress{std::cout, config.events};
progress.increment(events.size());
events.reserve(config.events);
for(; events.size() < static_cast<size_t>(config.events); ++trials){
auto ev = generator.gen_event();
++status_counter[generator.status()];
if(generator.status() == HEJFOG::good && analysis->pass_cuts(ev, ev)) {
if(unweighter) {
auto unweighted = unweighter->unweight(std::move(ev));
if(! unweighted) continue;
ev = std::move(*unweighted);
}
events.emplace_back(std::move(ev));
++progress;
}
}
std::cout << std::endl;
HEJFOG::CrossSectionAccumulator xs;
for(auto & ev: events){
rescale_weights(ev, invGeV2_to_pb/trials);
analysis->fill(ev, ev);
writer.write(ev);
xs.fill(ev);
}
analysis->finalise();
const std::chrono::duration<double> run_time = (clock::now() - start_time);
std::cout << "\nTask Runtime: " << run_time.count() << " seconds.\n\n";
std::cout.precision(10);
std::cout.setf(std::ios::fixed);
std::cout
<< " " << std::left << std::setw(20)
<< "Cross section: " << xs.total().value
<< " +- " << std::sqrt(xs.total().error) << " (pb)\n";
for(auto const & xs_type: xs) {
std::cout
<< " " << std::left << std::setw(20)
<< (RHEJ::event_type::names[xs_type.first] + ": "s)
<< xs_type.second.value << " +- "
<< std::sqrt(xs_type.second.error) << " (pb)\n";
}
std::cout << '\n';
for(auto && entry: status_counter){
const double fraction = static_cast<double>(entry.second)/trials;
const int percent = std::round(100*fraction);
std::cout << "status "
<< std::left << std::setw(16) << (to_string(entry.first) + ":")
<< " [";
for(int i = 0; i < percent/2; ++i) std::cout << '#';
for(int i = percent/2; i < 50; ++i) std::cout << ' ';
std::cout << "] " << percent << "%\n";
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Jan 20, 8:36 PM (12 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4241132
Default Alt Text
(11 KB)
Attached To
rHEJ HEJ
Event Timeline
Log In to Comment