TTTT Analysis  0.1
container.hpp
1 #ifndef root_container_hpp
2 #define root_container_hpp
3 #include <iostream>
4 #include <utility>
5 #include <map>
6 
7 #include "TROOT.h"
8 #include "TFile.h"
9 #include "TCanvas.h"
10 #include "TGraph.h"
11 #include "TH1.h"
12 #include "TH2.h"
13 
14 #include "TMVA/Factory.h"
15 #include "TMVA/DataLoader.h"
16 #include "TMVA/DataSetInfo.h"
17 
18 #include "filval/container.hpp"
19 
20 namespace fv::root::util{
26  void save_as(TObject* container, const std::string& fname, const SaveOption& option = SaveOption::PNG) {
27 
28  auto save_img = [](TObject* container, const std::string& fname){
29  TCanvas* c1 = new TCanvas("c1");
30  container->Draw();
31  c1->Draw();
32  c1->SaveAs(fname.c_str());
33  delete c1;
34  };
35 
36  auto save_bin = [](TObject* container){
37  INFO("Saving object: " << container->GetName() << " into file " << gDirectory->GetName());
38  container->Write(container->GetName(), TObject::kOverwrite);
39  };
40 
41  switch(option){
42  case PNG:
43  save_img(container, fname+".png"); break;
44  case PDF:
45  save_img(container, fname+".pdf"); break;
46  case ROOT:
47  save_bin(container); break;
48  default:
49  break;
50  }
51  }
52 
53 
65  void save_as_stl(void* container, const std::string& type_name,
66  const std::string& obj_name,
67  const SaveOption& option = SaveOption::PNG) {
68  switch(option){
69  case PNG:
70  INFO("Cannot save STL container " << type_name <<" as png");
71  break;
72  case PDF:
73  INFO("Cannot save STL container " << type_name <<" as pdf");
74  break;
75  case ROOT:
76  gDirectory->WriteObjectAny(container, type_name.c_str(), obj_name.c_str());
77  break;
78  default:
79  break;
80  }
81  }
82 }
83 
84 namespace fv::root {
85 
86 template <typename V>
87 class _ContainerTH1 : public Container<TH1,V>{
88  private:
89  void _fill(){
90  if (this->container == nullptr){
91  if (this->value == nullptr){
92  CRITICAL("Container: \"" << this->get_name() << "\" has a null Value object. "
93  << "Probably built with imcompatible type",-1);
94  }
95  this->container = new TH1D(this->get_name().c_str(), this->title.c_str(),
96  this->nbins, this->low, this->high);
97  this->container->SetXTitle(label_x.c_str());
98  this->container->SetYTitle(label_y.c_str());
99  }
100  _do_fill();
101  }
102 
103  protected:
104  std::string title;
105  std::string label_x;
106  std::string label_y;
107  int nbins;
108  double low;
109  double high;
110 
111  virtual void _do_fill() = 0;
112 
113  public:
114  explicit _ContainerTH1(const std::string &name, const std::string& title, Value<V>* value,
115  int nbins, double low, double high,
116  const std::string& label_x = "",
117  const std::string& label_y = "")
118  :Container<TH1,V>(name, value),
119  title(title), nbins(nbins), low(low), high(high),
120  label_x(label_x), label_y(label_y) { }
121 
122  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
123  util::save_as(this->get_container(), fname, option);
124  }
125 };
126 
127 template <typename V>
128 class ContainerTH1 : public _ContainerTH1<V>{
129  using _ContainerTH1<V>::_ContainerTH1;
130  void _do_fill(){
131  this->container->Fill(this->value->get_value());
132  }
133 };
134 
135 template <typename V>
136 class ContainerTH1Many : public _ContainerTH1<std::vector<V>>{
137  using _ContainerTH1<std::vector<V>>::_ContainerTH1;
138  void _do_fill(){
139  for(V x : this->value->get_value())
140  this->container->Fill(x);
141  }
142 };
143 
144 
145 
146 template <typename V>
147 class _ContainerTH2 : public Container<TH2,std::pair<V,V>>{
148  private:
149  void _fill(){
150  if (this->container == nullptr){
151  if (this->value == nullptr){
152  CRITICAL("Container: \"" << this->get_name() << "\" has a null Value object. "
153  << "Probably built with imcompatible type",-1);
154  }
155  this->container = new TH2D(this->get_name().c_str(), this->title.c_str(),
156  this->nbins_x, this->low_x, this->high_x,
157  this->nbins_y, this->low_y, this->high_y);
158  this->container->SetXTitle(label_x.c_str());
159  this->container->SetYTitle(label_y.c_str());
160  }
161  _do_fill(this->value->get_value());
162  }
163 
164  protected:
165  std::string title;
166  std::string label_x;
167  std::string label_y;
168  int nbins_x;
169  int nbins_y;
170  double low_x;
171  double low_y;
172  double high_x;
173  double high_y;
174 
175  virtual void _do_fill(std::pair<V,V>& val) = 0;
176 
177  public:
178  explicit _ContainerTH2(const std::string& name, const std::string& title,
179  Value<std::pair<V, V>>* value,
180  int nbins_x, double low_x, double high_x,
181  int nbins_y, double low_y, double high_y,
182  const std::string& label_x = "",
183  const std::string& label_y = "")
184  :Container<TH2,std::pair<V,V>>(name, value),
185  title(title),
186  nbins_x(nbins_x), low_x(low_x), high_x(high_x),
187  nbins_y(nbins_y), low_y(low_y), high_y(high_y),
188  label_x(label_x), label_y(label_y) { }
189 
190  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
191  util::save_as(this->get_container(), fname, option);
192  }
193 };
194 
195 template <typename V>
196 class ContainerTH2 : public _ContainerTH2<V>{
197  using _ContainerTH2<V>::_ContainerTH2;
198  void _do_fill(std::pair<V,V>& val){
199  this->container->Fill(val.first,val.second);
200  }
201 };
202 
203 template <typename V>
204 class ContainerTH2Many : public _ContainerTH2<std::vector<V>>{
205  using _ContainerTH2<std::vector<V>>::_ContainerTH2;
206  void _do_fill(std::pair<std::vector<V>,std::vector<V>>& val){
207  int min_size = std::min(val.first.size(), val.second.size());
208  for(int i=0; i<min_size; i++)
209  this->container->Fill(val.first[i],val.second[i]);
210  }
211 };
212 
213 template <typename V>
214 class ContainerTGraph : public Container<TGraph,std::pair<V,V>>{
215  private:
216  std::vector<V> x_data;
217  std::vector<V> y_data;
218  std::string title;
219  bool data_modified;
220  void _fill(){
221  auto val = this->value->get_value();
222  x_data.push_back(val.first);
223  y_data.push_back(val.second);
224  data_modified = true;
225  }
226  public:
227  ContainerTGraph(const std::string& name, const std::string& title, Value<std::pair<V, V>>* value)
228  :Container<TGraph,std::pair<V,V>>(name, value),
229  data_modified(false){
230  this->container = new TGraph();
231  }
232 
233  TGraph* get_container(){
234  if (data_modified){
235  delete this->container;
236  this->container = new TGraph(x_data.size(), x_data.data(), y_data.data());
237  this->container->SetName(this->get_name().c_str());
238  this->container->SetTitle(title.c_str());
239  data_modified = false;
240  }
241  return this->container;
242  }
243  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
244  util::save_as(get_container(), fname, option);
245  }
246 };
247 
248 template <typename T>
249 class Vector : public Container<std::vector<T>,T>{
250  private:
251 
252  void _fill(){
253  this->container->push_back(this->value->get_value());
254  }
255  public:
256  Vector(const std::string& name, Value<T>* value)
257  :Container<std::vector<T>,T>(name, value){
258  this->container = new std::vector<T>;
259  }
260 
261  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
262  std::string type_name = "std::vector<"+fv::util::get_type_name(typeid(T))+">";
263  util::save_as_stl(this->get_container(), type_name, this->get_name(), option);
264  }
265 };
266 
267 template <typename V, typename D>
268 class _Counter : public Container<std::map<D,int>,V>{
269  public:
270  explicit _Counter(const std::string& name, Value<V>* value)
271  :Container<std::map<D,int>,V>(name, value) {
272  this->container = new std::map<D,int>;
273  }
274 
275  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
276  std::string type_name = "std::map<"+fv::util::get_type_name(typeid(D))+",int>";
277  util::save_as_stl(this->get_container(), type_name, this->get_name(), option);
278  }
279 
280 };
281 
282 
287 template <typename V>
288 class Counter : public _Counter<V,V>{
289  using _Counter<V,V>::_Counter;
290  void _fill(){
291  (*this->container)[this->value->get_value()]++;
292  }
293 };
294 
298 template <typename V>
299 class CounterMany : public _Counter<std::vector<V>,V>{
300  using _Counter<std::vector<V>,V>::_Counter;
301  void _fill(){
302  for(V& val : this->value->get_value())
303  (*this->container)[val]++;
304  }
305 };
306 
307 
308 template <typename... ArgTypes>
309 class MVA : public Container<TMVA::DataLoader,typename MVAData<ArgTypes...>::type>{
310  private:
311  std::vector<std::pair<std::string,std::string>> methods;
312 
313  TCut cut;
314  TString opt;
315 
316  void _fill(){
317  std::tuple<ArgTypes...> t;
318  typename MVAData<ArgTypes...>::type& event = this->value->get_value();
319  bool is_training, is_signal;
320  double weight;
321  std::tie(is_training, is_signal, weight, t) = event;
322  std::vector<double> v = t2v<double>(t);
323  if (is_signal){
324  if (is_training){
325  this->container->AddSignalTrainingEvent(v, weight);
326  } else {
327  this->container->AddSignalTestEvent(v, weight);
328  }
329  } else {
330  if (is_training){
331  this->container->AddBackgroundTrainingEvent(v, weight);
332  } else {
333  this->container->AddBackgroundTestEvent(v, weight);
334  }
335  }
336  }
337  public:
338  MVA(const std::string& name, MVAData<ArgTypes...>* value, const std::string& cut = "", const std::string& opt = "")
339  :Container<TMVA::DataLoader,typename MVAData<ArgTypes...>::type>(name, value),
340  cut(cut.c_str()), opt(opt.c_str()) {
341  this->container = new TMVA::DataLoader(name);
342  for (std::pair<std::string,char>& p : value->get_label_types()){
343  this->container->AddVariable(p.first, p.second);
344  }
345  }
346 
347  void add_method(const std::string& method_name, const std::string& method_params) {
348  methods.push_back(std::make_pair(method_name, method_params));
349  }
350 
351  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
352  TFile* outputFile = gDirectory->GetFile();
353 
354  this->container->PrepareTrainingAndTestTree(cut, opt);
355  TMVA::Factory *factory = new TMVA::Factory("TMVAClassification", outputFile,
356  "!V:!Silent:Color:DrawProgressBar:Transformations=I;D;P;G,D:AnalysisType=Classification");
357 
358  TMVA::Types& types = TMVA::Types::Instance();
359  for(auto& p : methods){
360  std::string method_name, method_params;
361  std::tie(method_name, method_params) = p;
362  TMVA::Types::EMVA method_type = types.GetMethodType(method_name);
363  factory->BookMethod(this->container, method_type, method_name, method_params);
364  }
365 
366  // Train MVAs using the set of training events
367  factory->TrainAllMethods();
368  // Evaluate all MVAs using the set of test events
369  factory->TestAllMethods();
370  // Evaluate and compare performance of all configured MVAs
371  factory->EvaluateAllMethods();
372 
373  delete factory;
374  }
375 };
376 }
377 #endif // root_container_hpp
Same as Counter but accepts multiple values per fill.
Definition: container.hpp:299
A Counter that keeps a mapping of the number of occurances of each input value.
Definition: container.hpp:288
STL namespace.
SaveOption
Enumeration of different options that can be used to save Containers.
Definition: container.hpp:69
Definition: api.hpp:8
A class that is used to "hold" values.
Definition: container.hpp:132