Belle II Software  release-06-00-14
Utility.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <mva/utility/Utility.h>
10 #include <mva/utility/DataDriven.h>
11 #include <mva/methods/PDF.h>
12 #include <mva/methods/Reweighter.h>
13 #include <mva/methods/Trivial.h>
14 #include <mva/methods/Combination.h>
15 
16 #include <framework/logging/Logger.h>
17 
18 #include <framework/utilities/MakeROOTCompatible.h>
19 
20 #include <boost/algorithm/string/predicate.hpp>
21 #include <boost/property_tree/xml_parser.hpp>
22 
23 #include <iostream>
24 #include <chrono>
25 #include <string>
26 #include <regex>
27 #include <fstream>
28 
29 namespace Belle2 {
34  namespace MVA {
35 
36  void loadRootDictionary() { }
37 
38  void download(const std::string& identifier, const std::string& filename, int experiment, int run, int event)
39  {
40  Belle2::EventMetaData emd(event, run, experiment);
42  if (boost::ends_with(filename, ".root")) {
43  Belle2::MVA::Weightfile::saveToROOTFile(weightfile, filename);
44  } else if (boost::ends_with(filename, ".xml")) {
45  Belle2::MVA::Weightfile::saveToXMLFile(weightfile, filename);
46  } else {
47  std::cerr << "Unknown file extension, fallback to xml" << std::endl;
48  Belle2::MVA::Weightfile::saveToXMLFile(weightfile, filename);
49  }
50  }
51 
52  void upload(const std::string& filename, const std::string& identifier, int exp1, int run1, int exp2, int run2)
53  {
54  Belle2::IntervalOfValidity iov(exp1, run1, exp2, run2);
55  Belle2::MVA::Weightfile weightfile;
56  if (boost::ends_with(filename, ".root")) {
57  weightfile = Belle2::MVA::Weightfile::loadFromROOTFile(filename);
58  } else if (boost::ends_with(filename, ".xml")) {
59  weightfile = Belle2::MVA::Weightfile::loadFromXMLFile(filename);
60  } else {
61  std::cerr << "Unknown file extension, fallback to xml" << std::endl;
62  weightfile = Belle2::MVA::Weightfile::loadFromXMLFile(filename);
63  }
64  Belle2::MVA::Weightfile::saveToDatabase(weightfile, identifier, iov);
65  }
66 
67  void upload_array(const std::vector<std::string>& filenames, const std::string& identifier, int exp1, int run1, int exp2, int run2)
68  {
69  Belle2::IntervalOfValidity iov(exp1, run1, exp2, run2);
70 
71  std::vector<Belle2::MVA::Weightfile> weightfiles;
72  for (const auto& filename : filenames) {
73 
74  Belle2::MVA::Weightfile weightfile;
75  if (boost::ends_with(filename, ".root")) {
76  weightfile = Belle2::MVA::Weightfile::loadFromROOTFile(filename);
77  } else if (boost::ends_with(filename, ".xml")) {
78  weightfile = Belle2::MVA::Weightfile::loadFromXMLFile(filename);
79  } else {
80  std::cerr << "Unknown file extension, fallback to xml" << std::endl;
81  weightfile = Belle2::MVA::Weightfile::loadFromXMLFile(filename);
82  }
83  weightfiles.push_back(weightfile);
84  }
85  Belle2::MVA::Weightfile::saveArrayToDatabase(weightfiles, identifier, iov);
86  }
87 
88  void extract(const std::string& filename, const std::string& directory)
89  {
90 
92  auto supported_interfaces = AbstractInterface::getSupportedInterfaces();
93  auto weightfile = Weightfile::load(filename);
94  weightfile.setRemoveTemporaryDirectories(false);
95  weightfile.setTemporaryDirectory(directory);
96  GeneralOptions general_options;
97  weightfile.getOptions(general_options);
98  auto expertLocal = supported_interfaces[general_options.m_method]->getExpert();
99  expertLocal->load(weightfile);
100 
101  }
102 
103  std::string info(const std::string& filename)
104  {
105 
107  auto supported_interfaces = AbstractInterface::getSupportedInterfaces();
108  auto weightfile = Weightfile::load(filename);
109  GeneralOptions general_options;
110  weightfile.getOptions(general_options);
111 
112  auto specific_options = supported_interfaces[general_options.m_method]->getOptions();
113  specific_options->load(weightfile.getXMLTree());
114 
115  boost::property_tree::ptree temp_tree;
116  general_options.save(temp_tree);
117  specific_options->save(temp_tree);
118  std::ostringstream oss;
119 
120 #if BOOST_VERSION < 105600
121  boost::property_tree::xml_writer_settings<char> settings('\t', 1);
122 #else
123  boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
124 #endif
125  boost::property_tree::xml_parser::write_xml(oss, temp_tree, settings);;
126 
127  return oss.str();
128 
129  }
130 
131  bool available(const std::string& filename, int experiment, int run, int event)
132  {
133 
134  try {
135  auto weightfile = Weightfile::load(filename, Belle2::EventMetaData(event, run, experiment));
136  return true;
137  } catch (...) {
138  return false;
139  }
140 
141  }
142 
143  void expert(const std::vector<std::string>& filenames, const std::vector<std::string>& datafiles, const std::string& treename,
144  const std::string& outputfile, int experiment, int run, int event, bool copy_target)
145  {
146 
147  std::vector<Weightfile> weightfiles;
148  std::vector<TBranch*> branches;
149 
150  TFile file(outputfile.c_str(), "RECREATE");
151  file.cd();
152  TTree tree("variables", "variables");
153  float result = 0;
154 
155  for (auto& filename : filenames) {
156  Belle2::EventMetaData emd(event, run, experiment);
157  auto weightfile = Weightfile::load(filename, emd);
158  weightfiles.push_back(weightfile);
159 
160  std::string branchname = Belle2::makeROOTCompatible(filename);
161  auto branch = tree.Branch(branchname.c_str(), &result, (branchname + "/F").c_str());
162  branches.push_back(branch);
163  }
164 
166  auto supported_interfaces = AbstractInterface::getSupportedInterfaces();
167 
168  unsigned int i = 0;
169  for (auto& weightfile : weightfiles) {
170  GeneralOptions general_options;
171  weightfile.getOptions(general_options);
172  general_options.m_treename = treename;
173  // Override possible restriction of number of events in training
174  // otherwise this would apply to the expert as well.
175  general_options.m_max_events = 0;
176 
177  auto expertLocal = supported_interfaces[general_options.m_method]->getExpert();
178  expertLocal->load(weightfile);
179  // define if target variables should be copied
180  if (not copy_target) {
181  general_options.m_target_variable = std::string();
182  }
183 
184  general_options.m_datafiles = datafiles;
185  auto& branch = branches[i];
186  ROOTDataset data(general_options);
187  std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
188  auto results = expertLocal->apply(data);
189  std::chrono::high_resolution_clock::time_point stop = std::chrono::high_resolution_clock::now();
190  std::chrono::duration<double, std::milli> training_time = stop - start;
191  B2INFO("Elapsed application time in ms " << training_time.count() << " for " << general_options.m_identifier);
192  for (auto& r : results) {
193  result = r;
194  branch->Fill();
195  }
196 
197 
198  if (not general_options.m_target_variable.empty()) {
199  std::string branchname = Belle2::makeROOTCompatible(std::string(branch->GetName()) + "_" + general_options.m_target_variable);
200  float target = 0;
201  auto target_branch = tree.Branch(branchname.c_str(), &target, (branchname + "/F").c_str());
202  auto targets = data.getTargets();
203  for (auto& t : targets) {
204  target = t;
205  target_branch->Fill();
206  }
207  }
208 
209  ++i;
210  }
211 
212  tree.SetEntries();
213  file.Write("variables");
214 
215  }
216 
217  void save_custom_weightfile(const GeneralOptions& general_options, const SpecificOptions& specific_options,
218  const std::string& custom_weightfile, const std::string& output_identifier)
219  {
220  std::ifstream ifile(custom_weightfile);
221  if (!(bool)ifile) {
222  B2FATAL("Input weight file: " << custom_weightfile << " does not exist!");
223  }
224 
225  Weightfile weightfile;
226  weightfile.addOptions(general_options);
227  weightfile.addOptions(specific_options);
228  weightfile.addFile(general_options.m_identifier + "_Weightfile", custom_weightfile);
229  std::string output_weightfile(custom_weightfile);
230  if (!output_identifier.empty()) {
231  std::regex to_replace("(\\.\\S+$)");
232  std::string replacement = "_" + output_identifier + "$0";
233  output_weightfile = std::regex_replace(output_weightfile, to_replace, replacement);
234  }
235  Weightfile::save(weightfile, output_weightfile);
236  }
237 
238  void teacher(const GeneralOptions& general_options, const SpecificOptions& specific_options, const MetaOptions& meta_options)
239  {
240  unsigned int number_of_enabled_meta_trainings = 0;
241  if (meta_options.m_use_splot)
242  number_of_enabled_meta_trainings++;
243  if (meta_options.m_use_sideband_subtraction)
244  number_of_enabled_meta_trainings++;
245  if (meta_options.m_use_reweighting)
246  number_of_enabled_meta_trainings++;
247 
248  if (number_of_enabled_meta_trainings > 1) {
249  B2ERROR("You enabled more than one meta training option. You can only use one (sPlot, SidebandSubstraction or Reweighting)");
250  return;
251  }
252 
253  if (meta_options.m_use_splot) {
254  teacher_splot(general_options, specific_options, meta_options);
255  } else if (meta_options.m_use_sideband_subtraction) {
256  teacher_sideband_subtraction(general_options, specific_options, meta_options);
257  } else if (meta_options.m_use_reweighting) {
258  teacher_reweighting(general_options, specific_options, meta_options);
259  } else {
260  ROOTDataset data(general_options);
261  teacher_dataset(general_options, specific_options, data);
262  }
263  }
264 
265 
266  std::unique_ptr<Belle2::MVA::Expert> teacher_dataset(GeneralOptions general_options, const SpecificOptions& specific_options,
267  Dataset& data)
268  {
269  if (general_options.m_method.empty()) {
270  general_options.m_method = specific_options.getMethod();
271  } else {
272  if (general_options.m_method != specific_options.getMethod()) {
273  B2ERROR("The method specified in the general options is in conflict with the provided specific option:" << general_options.m_method
274  << " " << specific_options.getMethod());
275  }
276  }
278  auto supported_interfaces = AbstractInterface::getSupportedInterfaces();
279  if (supported_interfaces.find(general_options.m_method) != supported_interfaces.end()) {
280  auto teacherLocal = supported_interfaces[general_options.m_method]->getTeacher(general_options, specific_options);
281  std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
282  auto weightfile = teacherLocal->train(data);
283  std::chrono::high_resolution_clock::time_point stop = std::chrono::high_resolution_clock::now();
284  std::chrono::duration<double, std::milli> training_time = stop - start;
285  B2INFO("Elapsed training time in ms " << training_time.count() << " for " << general_options.m_identifier);
286  Weightfile::save(weightfile, general_options.m_identifier);
287  auto expertLocal = supported_interfaces[general_options.m_method]->getExpert();
288  expertLocal->load(weightfile);
289  return expertLocal;
290  } else {
291  B2ERROR("Interface doesn't support chosen method" << general_options.m_method);
292  throw std::runtime_error("Interface doesn't support chosen method" + general_options.m_method);
293  }
294  }
295 
296  std::unique_ptr<Belle2::MVA::Expert> teacher_splot(const GeneralOptions& general_options, const SpecificOptions& specific_options,
297  const MetaOptions& meta_options)
298  {
299 
300  GeneralOptions data_general_options = general_options;
301  data_general_options.m_target_variable = "";
302  if (meta_options.m_splot_combined)
303  data_general_options.m_identifier = general_options.m_identifier + "_splot.xml";
304  ROOTDataset data_dataset(data_general_options);
305  // Reset target variable so that it shows up in the weightfile at the end
306  data_general_options.m_target_variable = general_options.m_target_variable;
307 
308  GeneralOptions discriminant_general_options = general_options;
309  discriminant_general_options.m_target_variable = "";
310  discriminant_general_options.m_variables = {meta_options.m_splot_variable};
311  ROOTDataset discriminant_dataset(discriminant_general_options);
312  // Reset target variable so that it shows up in the weightfile at the end
313  discriminant_general_options.m_target_variable = general_options.m_target_variable;
314 
315  GeneralOptions mc_general_options = general_options;
316  mc_general_options.m_datafiles = meta_options.m_splot_mc_files;
317  mc_general_options.m_variables = {meta_options.m_splot_variable};
318  ROOTDataset mc_dataset(mc_general_options);
319 
320  auto mc_signals = mc_dataset.getSignals();
321  auto mc_weights = mc_dataset.getWeights();
322  auto mc_feature = mc_dataset.getFeature(0);
323  auto data_feature = discriminant_dataset.getFeature(0);
324  auto data_weights = discriminant_dataset.getWeights();
325 
326  Binning binning = Binning::CreateEqualFrequency(mc_feature , mc_weights, mc_signals, 100);
327 
328  float signalFraction = binning.m_signal_yield / (binning.m_signal_yield + binning.m_bckgrd_yield);
329 
330  std::vector<double> data(100, 0);
331  double total_data = 0.0;
332  for (unsigned int iEvent = 0; iEvent < data_dataset.getNumberOfEvents(); ++iEvent) {
333  data[binning.getBin(data_feature[iEvent])] += data_weights[iEvent];
334  total_data += data_weights[iEvent];
335  }
336 
337  // We do a simple fit here to estimate the signal and background yields
338  // We could use RooFit here to avoid using custom code,
339  // but I found RooFit to be difficult and unstable ...
340 
341  float best_yield = 0.0;
342  double best_chi2 = 1000000000.0;
343  bool empty_bin = false;
344  for (double yield = 0; yield < total_data; yield += 1) {
345  double chi2 = 0.0;
346  for (unsigned int iBin = 0; iBin < 100; ++iBin) {
347  double deviation = (data[iBin] - (yield * binning.m_signal_pdf[iBin] + (total_data - yield) * binning.m_bckgrd_pdf[iBin]) *
348  (binning.m_boundaries[iBin + 1] - binning.m_boundaries[iBin]) / (binning.m_boundaries[100] - binning.m_boundaries[0]));
349  if (data[iBin] > 0)
350  chi2 += deviation * deviation / data[iBin];
351  else
352  empty_bin = true;
353  }
354  if (chi2 < best_chi2) {
355  best_chi2 = chi2;
356  best_yield = yield;
357  }
358  }
359 
360  if (empty_bin) {
361  B2WARNING("Encountered empty bin in data histogram during fit of the components for sPlot");
362  }
363 
364  B2INFO("sPlot best yield " << best_yield);
365  B2INFO("sPlot Yields On MC " << binning.m_signal_yield << " " << binning.m_bckgrd_yield);
366 
367  binning.m_signal_yield = best_yield;
368  binning.m_bckgrd_yield = (total_data - best_yield);
369 
370  B2INFO("sPlot Yields Fitted On Data " << binning.m_signal_yield << " " << binning.m_bckgrd_yield);
371 
372  if (meta_options.m_splot_boosted) {
373  GeneralOptions boost_general_options = data_general_options;
374  boost_general_options.m_identifier = general_options.m_identifier + "_boost.xml";
375  SPlotDataset splot_dataset(boost_general_options, data_dataset, getBoostWeights(discriminant_dataset, binning), signalFraction);
376  auto boost_expert = teacher_dataset(boost_general_options, specific_options, splot_dataset);
377 
378  SPlotDataset aplot_dataset(data_general_options, data_dataset, getAPlotWeights(discriminant_dataset, binning,
379  boost_expert->apply(data_dataset)), signalFraction);
380  auto splot_expert = teacher_dataset(data_general_options, specific_options, aplot_dataset);
381  if (not meta_options.m_splot_combined)
382  return splot_expert;
383  } else {
384  SPlotDataset splot_dataset(data_general_options, data_dataset, getSPlotWeights(discriminant_dataset, binning), signalFraction);
385  auto splot_expert = teacher_dataset(data_general_options, specific_options, splot_dataset);
386  if (not meta_options.m_splot_combined)
387  return splot_expert;
388  }
389 
390  mc_general_options.m_identifier = general_options.m_identifier + "_pdf.xml";
391  mc_general_options.m_method = "PDF";
392  PDFOptions pdf_options;
393  // cppcheck-suppress unreadVariable
394  auto pdf_expert = teacher_dataset(mc_general_options, pdf_options, mc_dataset);
395 
396  GeneralOptions combination_general_options = general_options;
397  combination_general_options.m_method = "Combination";
398  combination_general_options.m_variables.push_back(meta_options.m_splot_variable);
399  CombinationOptions combination_options;
400  combination_options.m_weightfiles = {data_general_options.m_identifier, mc_general_options.m_identifier};
401  auto combination_expert = teacher_dataset(combination_general_options, combination_options, data_dataset);
402 
403  return combination_expert;
404  }
405 
406  std::unique_ptr<Belle2::MVA::Expert> teacher_reweighting(const GeneralOptions& general_options,
407  const SpecificOptions& specific_options,
408  const MetaOptions& meta_options)
409  {
410  if (std::find(general_options.m_variables.begin(), general_options.m_variables.end(),
411  meta_options.m_reweighting_variable) != general_options.m_variables.end()) {
412  B2ERROR("You cannot use the reweighting variable as a feature in your training");
413  return nullptr;
414  }
415 
416  GeneralOptions data_general_options = general_options;
417  data_general_options.m_target_variable = "";
418  data_general_options.m_datafiles = meta_options.m_reweighting_data_files;
419  ROOTDataset data_dataset(data_general_options);
420 
421  GeneralOptions mc_general_options = general_options;
422  mc_general_options.m_datafiles = meta_options.m_reweighting_mc_files;
423  ROOTDataset mc_dataset(mc_general_options);
424 
425  CombinedDataset boost_dataset(general_options, data_dataset, mc_dataset);
426 
427  GeneralOptions boost_general_options = general_options;
428  boost_general_options.m_identifier = general_options.m_identifier + "_boost.xml";
429  // cppcheck-suppress unreadVariable
430  auto boost_expert = teacher_dataset(boost_general_options, specific_options, boost_dataset);
431 
432  GeneralOptions reweighter_general_options = general_options;
433  reweighter_general_options.m_identifier = meta_options.m_reweighting_identifier;
434  reweighter_general_options.m_method = "Reweighter";
435  ReweighterOptions reweighter_specific_options;
436  reweighter_specific_options.m_weightfile = boost_general_options.m_identifier;
437  reweighter_specific_options.m_variable = meta_options.m_reweighting_variable;
438 
439  if (meta_options.m_reweighting_variable != "") {
440  if (std::find(reweighter_general_options.m_spectators.begin(), reweighter_general_options.m_spectators.end(),
441  meta_options.m_reweighting_variable) == reweighter_general_options.m_spectators.end() and
442  std::find(reweighter_general_options.m_variables.begin(), reweighter_general_options.m_variables.end(),
443  meta_options.m_reweighting_variable) == reweighter_general_options.m_variables.end() and
444  reweighter_general_options.m_target_variable != meta_options.m_reweighting_variable and
445  reweighter_general_options.m_weight_variable != meta_options.m_reweighting_variable) {
446  reweighter_general_options.m_spectators.push_back(meta_options.m_reweighting_variable);
447  }
448  }
449 
450  ROOTDataset dataset(reweighter_general_options);
451  auto reweight_expert = teacher_dataset(reweighter_general_options, reweighter_specific_options, dataset);
452  auto weights = reweight_expert->apply(dataset);
453  ReweightingDataset reweighted_dataset(general_options, dataset, weights);
454  auto expertLocal = teacher_dataset(general_options, specific_options, reweighted_dataset);
455 
456  return expertLocal;
457  }
458 
459  std::unique_ptr<Belle2::MVA::Expert> teacher_sideband_subtraction(const GeneralOptions& general_options,
460  const SpecificOptions& specific_options,
461  const MetaOptions& meta_options)
462  {
463 
464  if (std::find(general_options.m_variables.begin(), general_options.m_variables.end(),
465  meta_options.m_sideband_variable) != general_options.m_variables.end()) {
466  B2ERROR("You cannot use the sideband variable as a feature in your training");
467  return nullptr;
468  }
469 
470  GeneralOptions data_general_options = general_options;
471  if (std::find(data_general_options.m_spectators.begin(), data_general_options.m_spectators.end(),
472  meta_options.m_sideband_variable) == data_general_options.m_spectators.end()) {
473  data_general_options.m_spectators.push_back(meta_options.m_sideband_variable);
474  }
475  ROOTDataset data_dataset(data_general_options);
476 
477  GeneralOptions mc_general_options = general_options;
478  mc_general_options.m_datafiles = meta_options.m_sideband_mc_files;
479  if (std::find(mc_general_options.m_spectators.begin(), mc_general_options.m_spectators.end(),
480  meta_options.m_sideband_variable) == mc_general_options.m_spectators.end()) {
481  mc_general_options.m_spectators.push_back(meta_options.m_sideband_variable);
482  }
483  ROOTDataset mc_dataset(mc_general_options);
484 
485  GeneralOptions sideband_general_options = general_options;
486  SidebandDataset sideband_dataset(sideband_general_options, data_dataset, mc_dataset, meta_options.m_sideband_variable);
487  auto expertLocal = teacher_dataset(general_options, specific_options, sideband_dataset);
488 
489  return expertLocal;
490  }
491 
492 
493  }
495 }
Store event, run, and experiment numbers.
Definition: EventMetaData.h:33
A class that describes the interval of experiments/runs for which an object in the database is valid.
static std::map< std::string, AbstractInterface * > getSupportedInterfaces()
Returns interfaces supported by the MVA Interface.
Definition: Interface.h:53
static void initSupportedInterfaces()
Static function which initliazes all supported interfaces, has to be called once before getSupportedI...
Definition: Interface.cc:45
static Binning CreateEqualFrequency(const std::vector< float > &data, const std::vector< float > &weights, const std::vector< bool > &isSignal, unsigned int nBins)
Create an equal frequency (aka equal-statistics) binning.
Definition: Binning.cc:93
The Weightfile class serializes all information about a training into an xml tree.
Definition: Weightfile.h:38
static Weightfile loadFromXMLFile(const std::string &filename)
Static function which loads a Weightfile from a XML file.
Definition: Weightfile.cc:239
static void save(Weightfile &weightfile, const std::string &filename, const Belle2::IntervalOfValidity &iov=Belle2::IntervalOfValidity(0, 0, -1, -1))
Static function which saves a Weightfile to a file.
Definition: Weightfile.cc:153
void setRemoveTemporaryDirectories(bool remove_temporary_directories)
Set the deletion behaviour of the weightfile object for temporary directories For debugging it can be...
Definition: Weightfile.h:282
static void saveToXMLFile(Weightfile &weightfile, const std::string &filename)
Static function which saves a Weightfile to a XML file.
Definition: Weightfile.cc:174
const boost::property_tree::ptree & getXMLTree() const
Get xml tree.
Definition: Weightfile.h:292
void setTemporaryDirectory(const std::string &temporary_directory)
set temporary directory which is used to store temporary directories
Definition: Weightfile.h:287
void addOptions(const Options &options)
Add an Option object to the xml tree.
Definition: Weightfile.cc:61
static Weightfile loadFromROOTFile(const std::string &filename)
Static function which loads a Weightfile from a ROOT file.
Definition: Weightfile.cc:216
void getOptions(Options &options) const
Fills an Option object from the xml tree.
Definition: Weightfile.cc:66
static Weightfile load(const std::string &filename, const Belle2::EventMetaData &emd=Belle2::EventMetaData(0, 0, 0))
Static function which loads a Weightfile from a file or from the database.
Definition: Weightfile.cc:194
static Weightfile loadFromDatabase(const std::string &identifier, const Belle2::EventMetaData &emd=Belle2::EventMetaData(0, 0, 0))
Static function which loads a Weightfile from the basf2 condition database.
Definition: Weightfile.cc:280
static void saveToROOTFile(Weightfile &weightfile, const std::string &filename)
Static function which saves a Weightfile to a ROOT file.
Definition: Weightfile.cc:164
static void saveArrayToDatabase(const std::vector< Weightfile > &weightfiles, const std::string &identifier, const Belle2::IntervalOfValidity &iov=Belle2::IntervalOfValidity(0, 0, -1, -1))
Static function which saves an array of Weightfile objects in the basf2 condition database.
Definition: Weightfile.cc:266
static void saveToDatabase(Weightfile &weightfile, const std::string &identifier, const Belle2::IntervalOfValidity &iov=Belle2::IntervalOfValidity(0, 0, -1, -1))
Static function which saves a Weightfile in the basf2 condition database.
Definition: Weightfile.cc:257
std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.
Abstract base class for different kinds of events.