Version: SMASH-3.1
rivetoutput.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2021 Christian Holm Christensen
4  * Copyright (c) 2021-2022
5  * SMASH Team
6  *
7  * GNU General Public License (GPLv3 or later)
8  *
9  */
10 
11 #include "smash/rivetoutput.h"
12 
13 #include "Rivet/Rivet.hh"
14 #include "Rivet/Tools/Logging.hh"
15 
16 #include "smash/logging.h"
17 #include "smash/outputparameters.h"
18 
19 namespace smash {
91 RivetOutput::RivetOutput(const std::filesystem::path& path, std::string name,
92  const bool full_event,
93  const RivetOutputParameters& rivet_par)
94  : HepMcInterface(name, full_event),
95  handler_(),
96  filename_(path / (name + ".yoda")),
97  need_init_(true) {
98  handler_ = std::make_shared<Rivet::AnalysisHandler>();
99  setup(rivet_par);
100 }
101 
103  logg[LOutput].debug() << "Writing Rivet results to " << filename_
104  << std::endl;
105  analysis_handler_proxy()->finalize();
106  analysis_handler_proxy()->writeData(filename_.string());
107 }
108 
109 void RivetOutput::at_eventend(const Particles& particles,
110  const int32_t event_number,
111  const EventInfo& event) {
112  HepMcInterface::at_eventend(particles, event_number, event);
113 
114  // Initialize Rivet on first event
115  if (need_init_) {
116  logg[LOutput].debug() << "Initialising Rivet" << std::endl;
117  need_init_ = false;
119  }
120 
121  logg[LOutput].debug() << "Analysing event " << event_number << std::endl;
122  // Let Rivet analyse the event
123  analysis_handler_proxy()->analyze(event_);
124 }
125 
126 void RivetOutput::add_analysis(const std::string& name) {
127  analysis_handler_proxy()->addAnalysis(name);
128 }
129 
130 void RivetOutput::add_path(const std::string& path) {
131  Rivet::addAnalysisLibPath(path);
132  Rivet::addAnalysisDataPath(path);
133 }
134 
135 void RivetOutput::add_preload(const std::string& file) {
136  analysis_handler_proxy()->readData(file);
137 }
138 
139 void RivetOutput::set_ignore_beams(bool ignore) {
140  logg[LOutput].info() << "Ignore beams? " << (ignore ? "yes" : "no")
141  << std::endl;
142  analysis_handler_proxy()->setIgnoreBeams(ignore);
143 }
144 
145 void RivetOutput::set_log_level(const std::string& name,
146  const std::string& level) {
147  std::string fname(name);
148  if (fname.rfind("Rivet", 0) != 0) {
149  fname = "Rivet." + fname;
150  }
151 
152  auto upcase = [](const std::string& s) {
153  std::string out(s);
154  std::transform(out.begin(), out.end(), out.begin(),
155  [](char c) { return std::toupper(c); });
156  return out;
157  };
158 
159  try {
160  Rivet::Log::setLevel(fname, Rivet::Log::getLevelFromName(upcase(level)));
161  } catch (...) {
162  }
163 }
164 
165 void RivetOutput::set_cross_section(double xs, double xserr) {
166  analysis_handler_proxy()->setCrossSection(xs, xserr, true);
167 }
168 
170  logg[LOutput].debug() << "Setting up Rivet output:\n";
171 
172  // Paths to analyses libraries and data
173  if (params.paths) {
174  logg[LOutput].info() << "Processing paths\n";
175  for (auto p : params.paths.value())
176  add_path(p);
177  }
178 
179  // Data files to pre-load e.g., for centrality configurations
180  if (params.preloads) {
181  logg[LOutput].info() << "Processing preloads\n";
182  for (auto p : params.preloads.value())
183  add_preload(p);
184  }
185 
186  // Analyses (including options) to add to run
187  if (params.analyses) {
188  logg[LOutput].info() << "Processing analyses\n";
189  for (auto p : params.analyses.value())
190  add_analysis(p);
191  }
192 
193  // Whether Rivet should ignore beams
195 
196  // Cross sections
197  if (params.cross_sections) {
198  set_cross_section(params.cross_sections.value()[0],
199  params.cross_sections.value()[1]);
200  }
201 
202  // Logging in Rivet
203  if (params.logs) {
204  for (auto nl : params.logs.value())
205  set_log_level(nl.first, nl.second);
206  }
207 
208  // Treatment of event weights in Rivet
209  if (params.any_weight_parameter_was_given) {
210  // Do not care about multi weights
211  if (params.no_multi_weight) {
212  analysis_handler_proxy()->skipMultiWeights(
213  params.no_multi_weight.value());
214  }
215 
216  // Set nominal weight name
217  if (params.nominal_weight_name) {
218  analysis_handler_proxy()->setNominalWeightName(
219  params.nominal_weight_name.value());
220  }
221 
222  // Set cap (maximum) on weights
223  if (params.cap_on_weights) {
224  analysis_handler_proxy()->setWeightCap(params.cap_on_weights.value());
225  }
226 
227  // Whether to smear for NLO calculations
228  if (params.nlo_smearing) {
229  analysis_handler_proxy()->setNLOSmearing(params.nlo_smearing.value());
230  }
231 
232  // Select which weights to enable
233  if (params.to_be_enabled_weights) {
234  std::stringstream s;
235  int comma = 0;
236  for (auto w : params.to_be_enabled_weights.value())
237  s << (comma++ ? "," : "") << w;
238  analysis_handler_proxy()->selectMultiWeights(s.str());
239  }
240 
241  // Select weights to disable
242  if (params.to_be_disabled_weights) {
243  std::stringstream s;
244  int comma = 0;
245  for (auto w : params.to_be_disabled_weights.value())
246  s << (comma++ ? "," : "") << w;
247  analysis_handler_proxy()->deselectMultiWeights(s.str());
248  }
249  }
250  logg[LOutput].debug() << "Setup of Rivet output done.\n";
251 }
252 } // namespace smash
Base class for output handlers that need the HepMC3 structure.
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.
HepMC3::GenEvent event_
The event.
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
Proxy analysis_handler_proxy()
Return a proxy that temporarily disables FP exceptions.
Definition: rivetoutput.h:122
void add_path(const std::string &path)
Add a load path to the Rivet handler.
Definition: rivetoutput.cc:130
void add_analysis(const std::string &name)
Add an analysis or analyses to Rivet.
Definition: rivetoutput.cc:126
std::filesystem::path filename_
Output file.
Definition: rivetoutput.h:127
std::shared_ptr< Rivet::AnalysisHandler > handler_
Rivet analysis handler.
Definition: rivetoutput.h:125
bool need_init_
Whether we need initialisation.
Definition: rivetoutput.h:129
~RivetOutput()
Destructor.
Definition: rivetoutput.cc:102
void set_cross_section(double xs, double xserr)
Set X-section.
Definition: rivetoutput.cc:165
void add_preload(const std::string &file)
Add preload to Rivet handler.
Definition: rivetoutput.cc:135
void setup(const RivetOutputParameters &params)
Setup Rivet using SMASH configuration parameters.
Definition: rivetoutput.cc:169
void set_log_level(const std::string &name, const std::string &level)
Set log level in Rivet.
Definition: rivetoutput.cc:145
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:109
RivetOutput(const std::filesystem::path &path, std::string name, const bool full_event, const RivetOutputParameters &rivet_par)
Create Rivet output.
Definition: rivetoutput.cc:91
void set_ignore_beams(bool ignore=true)
Do not insist on appropriate beams for analyses.
Definition: rivetoutput.cc:139
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
constexpr int p
Proton.
Definition: action.h:24
static constexpr int LOutput
Structure to contain custom data for output.
Helper structure for OutputParameters in order to store and hand over Rivet parameters.
std::optional< std::vector< std::string > > to_be_enabled_weights
Weights to be enabled for processing.
std::optional< std::string > nominal_weight_name
Nominal weight name.
std::optional< std::map< std::string, std::string > > logs
Logging in Rivet.
std::optional< std::vector< std::string > > preloads
Data files to pre-load e.g., for centrality configurations.
std::optional< std::vector< std::string > > paths
Paths to analyses libraries and data.
std::optional< double > nlo_smearing
How to smear for NLO calculations.
std::optional< std::vector< std::string > > analyses
Analyses (including options) to add to run.
bool ignore_beams
Whether Rivet should ignore beams.
std::optional< double > cap_on_weights
Cap (maximum) on weights.
std::optional< bool > no_multi_weight
Whether Rivet should not care about multi weights.
std::optional< std::vector< std::string > > to_be_disabled_weights
Weights to be disabled for processing.
bool any_weight_parameter_was_given
Whether any weight parameter was specified.
std::optional< std::array< double, 2 > > cross_sections
Cross sections.