Version: SMASH-2.0.2
rivetoutput.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2021 Christian Holm Christensen
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/rivetoutput.h"
11 
12 #include <Rivet/Rivet.hh>
13 #include <Rivet/Tools/Logging.hh>
14 
15 #include "smash/logging.h"
16 
17 namespace smash {
146 RivetOutput::RivetOutput(const bf::path& path, std::string name,
147  const bool full_event, const int total_N,
148  const int proj_N, const OutputParameters& out_par)
149  : HepMcInterface(name, full_event, total_N, proj_N),
150  handler_(),
151  filename_(path / (name + ".yoda")),
152  need_init_(true),
153  rivet_confs_(out_par.subcon_for_rivet) {
154  handler_ = std::make_shared<Rivet::AnalysisHandler>();
155  setup();
156 }
157 
159  logg[LOutput].debug() << "Writing Rivet results to " << filename_
160  << std::endl;
161  analysis_handler_proxy()->finalize();
162  analysis_handler_proxy()->writeData(filename_.string());
163 }
164 
165 void RivetOutput::at_eventend(const Particles& particles,
166  const int32_t event_number,
167  const EventInfo& event) {
168  HepMcInterface::at_eventend(particles, event_number, event);
169 
170  // Initialize Rivet on first event
171  if (need_init_) {
172  logg[LOutput].debug() << "Initialising Rivet" << std::endl;
173  need_init_ = false;
175  }
176 
177  logg[LOutput].debug() << "Analysing event " << event_number << std::endl;
178  // Let Rivet analyse the event
179  analysis_handler_proxy()->analyze(event_);
180 }
181 
182 void RivetOutput::add_analysis(const std::string& name) {
183  analysis_handler_proxy()->addAnalysis(name);
184 }
185 
186 void RivetOutput::add_path(const std::string& path) {
187  Rivet::addAnalysisLibPath(path);
188  Rivet::addAnalysisDataPath(path);
189 }
190 
191 void RivetOutput::add_preload(const std::string& file) {
192  analysis_handler_proxy()->readData(file);
193 }
194 
195 void RivetOutput::set_ignore_beams(bool ignore) {
196  logg[LOutput].info() << "Ignore beams? " << (ignore ? "yes" : "no")
197  << std::endl;
198  analysis_handler_proxy()->setIgnoreBeams(ignore);
199 }
200 
201 void RivetOutput::set_log_level(const std::string& name,
202  const std::string& level) {
203  std::string fname(name);
204  if (fname.rfind("Rivet", 0) != 0) {
205  fname = "Rivet." + fname;
206  }
207 
208  auto upcase = [](const std::string& s) {
209  std::string out(s);
210  std::transform(out.begin(), out.end(), out.begin(),
211  [](char c) { return std::toupper(c); });
212  return out;
213  };
214 
215  try {
216  Rivet::Log::setLevel(fname, Rivet::Log::getLevelFromName(upcase(level)));
217  } catch (...) {
218  }
219 }
220 
221 void RivetOutput::set_cross_section(double xs, double xserr) {
222  analysis_handler_proxy()->setCrossSection(xs, xserr, true);
223 }
224 
226  logg[LOutput].debug() << "Setting up from configuration:\n"
227  << rivet_confs_.to_string() << std::endl;
228 
229  // Paths to analyses libraries and data
230  if (rivet_confs_.has_value({"Paths"})) {
231  logg[LOutput].info() << "Processing paths" << std::endl;
232  std::vector<std::string> path = rivet_confs_.take({"Paths"});
233  for (auto p : path)
234  add_path(p);
235  }
236 
237  // Data files to pre-load e.g., for centrality configurations
238  if (rivet_confs_.has_value({"Preloads"})) {
239  logg[LOutput].info() << "Processing preloads" << std::endl;
240  std::vector<std::string> prel = rivet_confs_.take({"Preloads"});
241  for (auto p : prel)
242  add_preload(p);
243  }
244 
245  // Analyses (including options) to add to run
246  if (rivet_confs_.has_value({"Analyses"})) {
247  logg[LOutput].info() << "Processing analyses" << std::endl;
248  std::vector<std::string> anas = rivet_confs_.take({"Analyses"});
249  for (auto p : anas)
250  add_analysis(p);
251  }
252 
253  // Whether Rivet should ignore beams
254  if (rivet_confs_.has_value({"Ignore_Beams"})) {
255  set_ignore_beams(rivet_confs_.take({"Ignore_Beams"}));
256  } else {
257  // we must explicity tell Rivet, through the handler, to ignore beam checks
258  set_ignore_beams(true);
259  }
260 
261  // Cross sections
262  if (rivet_confs_.has_value({"Cross_Section"})) {
263  std::array<double, 2> xs = rivet_confs_.take({"Cross_Section"});
264  set_cross_section(xs[0], xs[1]);
265  }
266 
267  // Logging in Rivet
268  if (rivet_confs_.has_value({"Logging"})) {
269  std::map<std::string, std::string> logs = rivet_confs_.take({"Logging"});
270  for (auto nl : logs)
271  set_log_level(nl.first, nl.second);
272  }
273 
274  // Treatment of event weights in Rivet
275  if (rivet_confs_.has_value({"Weights"})) {
276  auto wconf = rivet_confs_["Weights"];
277 
278  // Do not care about multi weights - bool
279  if (wconf.has_value({"No_Multi"})) {
280  analysis_handler_proxy()->skipMultiWeights(wconf.take({"No_Multi"}));
281  }
282 
283  // Set nominal weight name
284  if (wconf.has_value({"Nominal"})) {
285  analysis_handler_proxy()->setNominalWeightName(wconf.take({"Nominal"}));
286  }
287 
288  // Set cap (maximum) on weights
289  if (wconf.has_value({"Cap"})) {
290  analysis_handler_proxy()->setWeightCap(wconf.take({"Cap"}));
291  }
292 
293  // Whether to smear for NLO calculations
294  if (wconf.has_value({"NLO_Smearing"})) {
295  analysis_handler_proxy()->setNLOSmearing(wconf.take({"NLO_Smearing"}));
296  }
297 
298  // Select which weights to enable
299  if (wconf.has_value({"Select"})) {
300  std::vector<std::string> sel = wconf.take({"Select"});
301  std::stringstream s;
302  int comma = 0;
303  for (auto w : sel)
304  s << (comma++ ? "," : "") << w;
305  analysis_handler_proxy()->selectMultiWeights(s.str());
306  }
307 
308  // Select weights to disable
309  if (wconf.has_value({"Deselect"})) {
310  std::vector<std::string> sel = wconf.take({"Deselect"});
311  std::stringstream s;
312  int comma = 0;
313  for (auto w : sel)
314  s << (comma++ ? "," : "") << w;
315  analysis_handler_proxy()->deselectMultiWeights(s.str());
316  }
317  }
318  logg[LOutput].debug() << "After processing configuration:\n"
319  << rivet_confs_.to_string() << std::endl;
320 }
321 } // namespace smash
smash
Definition: action.h:24
smash::RivetOutput::analysis_handler_proxy
Proxy analysis_handler_proxy()
Return a proxy that temporarily disables FP exceptions.
Definition: rivetoutput.h:120
smash::RivetOutput::~RivetOutput
~RivetOutput()
Destructor.
Definition: rivetoutput.cc:158
smash::RivetOutput::setup
void setup()
Read configuration of Rivet from SMASH configuration.
Definition: rivetoutput.cc:225
smash::LOutput
static constexpr int LOutput
Definition: outputinterface.h:24
smash::HepMcInterface::event_
HepMC3::GenEvent event_
The event.
Definition: hepmcinterface.h:188
smash::RivetOutput::at_eventend
void at_eventend(const Particles &particles, const int32_t event_number, const EventInfo &event) override
Add the final particles information of an event to the central vertex.
Definition: rivetoutput.cc:165
smash::Configuration::to_string
std::string to_string() const
Returns a YAML string of the current tree.
Definition: configuration.cc:192
smash::Configuration::has_value
bool has_value(std::initializer_list< const char * > keys) const
Returns whether there is a non-empty value behind the requested keys.
Definition: configuration.cc:181
smash::RivetOutput::add_path
void add_path(const std::string &path)
Add a load path to the Rivet handler.
Definition: rivetoutput.cc:186
smash::EventInfo
Structure to contain custom data for output.
Definition: outputinterface.h:36
smash::logg
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
smash::OutputParameters
Helper structure for Experiment to hold output options and parameters.
Definition: outputparameters.h:25
smash::RivetOutput::need_init_
bool need_init_
Whether we need initialisation.
Definition: rivetoutput.h:127
smash::HepMcInterface::at_eventend
void at_eventend(const Particles &particles, const int32_t event_number, const EventInfo &event) override
Add the final particles information of an event to the central vertex.
Definition: hepmcinterface.cc:142
smash::RivetOutput::set_log_level
void set_log_level(const std::string &name, const std::string &level)
Set log level in Rivet.
Definition: rivetoutput.cc:201
smash::RivetOutput::add_analysis
void add_analysis(const std::string &name)
Add an analysis or analyses to Rivet.
Definition: rivetoutput.cc:182
smash::RivetOutput::filename_
bf::path filename_
Output file.
Definition: rivetoutput.h:125
smash::RivetOutput::RivetOutput
RivetOutput(const bf::path &path, std::string name, const bool full_event, const int total_N, const int proj_N, const OutputParameters &out_par)
Create Rivet output.
Definition: rivetoutput.cc:146
smash::HepMcInterface
Base class for output handlers that need the HepMC3 structure.
Definition: hepmcinterface.h:81
smash::Particles
Definition: particles.h:33
logging.h
smash::RivetOutput::rivet_confs_
Configuration rivet_confs_
Configutations for rivet.
Definition: rivetoutput.h:129
rivetoutput.h
smash::Configuration::take
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
Definition: configuration.cc:140
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::RivetOutput::add_preload
void add_preload(const std::string &file)
Add preload to Rivet handler.
Definition: rivetoutput.cc:191
smash::RivetOutput::set_cross_section
void set_cross_section(double xs, double xserr)
Set X-section.
Definition: rivetoutput.cc:221
smash::RivetOutput::handler_
std::shared_ptr< Rivet::AnalysisHandler > handler_
Rivet analysis handler.
Definition: rivetoutput.h:123
smash::RivetOutput::set_ignore_beams
void set_ignore_beams(bool ignore=true)
Do not insist on appropriate beams for analyses.
Definition: rivetoutput.cc:195