Page MenuHomeHEPForge

No OneTemporary

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

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)

Event Timeline