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  /* DEBUG("Writing object \"" << obj_name << "\" of type \"" << type_name << "\"\n"); */
77  gDirectory->WriteObjectAny(container, type_name.c_str(), obj_name.c_str());
78  break;
79  default:
80  break;
81  }
82  }
83 }
84 
85 namespace fv::root {
86 
87 template <typename V>
88 class _ContainerTH1 : public Container<TH1,V>{
89  private:
90  void _fill(){
91  if (this->container == nullptr){
92  if (this->value == nullptr){
93  CRITICAL("Container: \"" << this->get_name() << "\" has a null Value object. "
94  << "Probably built with imcompatible type",-1);
95  }
96  this->container = new TH1D(this->get_name().c_str(), this->title.c_str(),
97  this->nbins, this->low, this->high);
98  this->container->SetXTitle(label_x.c_str());
99  this->container->SetYTitle(label_y.c_str());
100  }
101  _do_fill();
102  }
103 
104  protected:
105  std::string title;
106  std::string label_x;
107  std::string label_y;
108  int nbins;
109  double low;
110  double high;
111 
112  virtual void _do_fill() = 0;
113 
114  public:
115  explicit _ContainerTH1(const std::string &name, const std::string& title, Value<V>* value,
116  int nbins, double low, double high,
117  const std::string& label_x = "",
118  const std::string& label_y = "")
119  :Container<TH1,V>(name, value),
120  title(title), nbins(nbins), low(low), high(high),
121  label_x(label_x), label_y(label_y) { }
122 
123  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
124  util::save_as(this->get_container(), fname, option);
125  }
126 };
127 
128 template <typename V>
129 class ContainerTH1 : public _ContainerTH1<V>{
130  using _ContainerTH1<V>::_ContainerTH1;
131  void _do_fill(){
132  this->container->Fill(this->value->get_value());
133  }
134 };
135 
136 template <typename V>
137 class ContainerTH1Many : public _ContainerTH1<std::vector<V>>{
138  using _ContainerTH1<std::vector<V>>::_ContainerTH1;
139  void _do_fill(){
140  for(V x : this->value->get_value())
141  this->container->Fill(x);
142  }
143 };
144 
145 
146 
147 template <typename V>
148 class _ContainerTH2 : public Container<TH2,std::pair<V,V>>{
149  private:
150  void _fill(){
151  if (this->container == nullptr){
152  if (this->value == nullptr){
153  CRITICAL("Container: \"" << this->get_name() << "\" has a null Value object. "
154  << "Probably built with imcompatible type",-1);
155  }
156  this->container = new TH2D(this->get_name().c_str(), this->title.c_str(),
157  this->nbins_x, this->low_x, this->high_x,
158  this->nbins_y, this->low_y, this->high_y);
159  this->container->SetXTitle(label_x.c_str());
160  this->container->SetYTitle(label_y.c_str());
161  }
162  _do_fill(this->value->get_value());
163  }
164 
165  protected:
166  std::string title;
167  std::string label_x;
168  std::string label_y;
169  int nbins_x;
170  int nbins_y;
171  double low_x;
172  double low_y;
173  double high_x;
174  double high_y;
175 
176  virtual void _do_fill(std::pair<V,V>& val) = 0;
177 
178  public:
179  explicit _ContainerTH2(const std::string& name, const std::string& title,
180  Value<std::pair<V, V>>* value,
181  int nbins_x, double low_x, double high_x,
182  int nbins_y, double low_y, double high_y,
183  const std::string& label_x = "",
184  const std::string& label_y = "")
185  :Container<TH2,std::pair<V,V>>(name, value),
186  title(title),
187  nbins_x(nbins_x), low_x(low_x), high_x(high_x),
188  nbins_y(nbins_y), low_y(low_y), high_y(high_y),
189  label_x(label_x), label_y(label_y) { }
190 
191  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
192  util::save_as(this->get_container(), fname, option);
193  }
194 };
195 
196 template <typename V>
197 class ContainerTH2 : public _ContainerTH2<V>{
198  using _ContainerTH2<V>::_ContainerTH2;
199  void _do_fill(std::pair<V,V>& val){
200  this->container->Fill(val.first,val.second);
201  }
202 };
203 
204 template <typename V>
205 class ContainerTH2Many : public _ContainerTH2<std::vector<V>>{
206  using _ContainerTH2<std::vector<V>>::_ContainerTH2;
207  void _do_fill(std::pair<std::vector<V>,std::vector<V>>& val){
208  int min_size = std::min(val.first.size(), val.second.size());
209  for(int i=0; i<min_size; i++)
210  this->container->Fill(val.first[i],val.second[i]);
211  }
212 };
213 
214 template <typename V>
215 class ContainerTGraph : public Container<TGraph,std::pair<V,V>>{
216  private:
217  std::vector<V> x_data;
218  std::vector<V> y_data;
219  std::string title;
220  bool data_modified;
221  void _fill(){
222  auto val = this->value->get_value();
223  x_data.push_back(val.first);
224  y_data.push_back(val.second);
225  data_modified = true;
226  }
227  public:
228  ContainerTGraph(const std::string& name, const std::string& title, Value<std::pair<V, V>>* value)
229  :Container<TGraph,std::pair<V,V>>(name, value),
230  data_modified(false){
231  this->container = new TGraph();
232  }
233 
234  TGraph* get_container(){
235  if (data_modified){
236  delete this->container;
237  this->container = new TGraph(x_data.size(), x_data.data(), y_data.data());
238  this->container->SetName(this->get_name().c_str());
239  this->container->SetTitle(title.c_str());
240  data_modified = false;
241  }
242  return this->container;
243  }
244  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
245  util::save_as(get_container(), fname, option);
246  }
247 };
248 
249 template <typename T>
250 class Vector : public Container<std::vector<T>,T>{
251  private:
252 
253  void _fill(){
254  this->container->push_back(this->value->get_value());
255  }
256  public:
257  Vector(const std::string& name, Value<T>* value)
258  :Container<std::vector<T>,T>(name, value){
259  this->container = new std::vector<T>;
260  }
261 
262  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
263  std::string type_name = "std::vector<"+fv::util::get_type_name(typeid(T))+">";
264  util::save_as_stl(this->get_container(), type_name, this->get_name(), option);
265  }
266 };
267 
268 template <typename V, typename D>
269 class _Counter : public Container<std::map<D,int>,V>{
270  public:
271  explicit _Counter(const std::string& name, Value<V>* value)
272  :Container<std::map<D,int>,V>(name, value) {
273  this->container = new std::map<D,int>;
274  }
275 
276  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
277  std::string type_name = "std::map<"+fv::util::get_type_name(typeid(D))+",int>";
278  util::save_as_stl(this->get_container(), type_name, this->get_name(), option);
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 class PassCount : public Container<int,bool>{
308  private:
309 
310  void _fill(){
311  if(this->value->get_value()){
312  (*this->container)++;
313  }
314  }
315  public:
316  PassCount(const std::string& name, Value<bool>* value)
317  :Container<int,bool>(name, value){
318  this->container = new int(0);
319  }
320 
321  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
322  //ROOT(hilariously) cannot serialize basic data types, we wrap this
323  //in a vector.
324  std::vector<int> v({*this->get_container()});
325  util::save_as_stl(&v, "std::vector<int>", this->get_name(), option);
326  }
327 };
328 
329 
330 template <typename... ArgTypes>
331 class MVA : public Container<TMVA::DataLoader,typename MVAData<ArgTypes...>::type>{
332  private:
333  std::vector<std::pair<std::string,std::string>> methods;
334 
335  TCut cut;
336  TString opt;
337 
338  void _fill(){
339  std::tuple<ArgTypes...> t;
340  typename MVAData<ArgTypes...>::type& event = this->value->get_value();
341  bool is_training, is_signal;
342  double weight;
343  std::tie(is_training, is_signal, weight, t) = event;
344  std::vector<double> v = t2v<double>(t);
345  if (is_signal){
346  if (is_training){
347  this->container->AddSignalTrainingEvent(v, weight);
348  } else {
349  this->container->AddSignalTestEvent(v, weight);
350  }
351  } else {
352  if (is_training){
353  this->container->AddBackgroundTrainingEvent(v, weight);
354  } else {
355  this->container->AddBackgroundTestEvent(v, weight);
356  }
357  }
358  }
359  public:
360  MVA(const std::string& name, MVAData<ArgTypes...>* value, const std::string& cut = "", const std::string& opt = "")
361  :Container<TMVA::DataLoader,typename MVAData<ArgTypes...>::type>(name, value),
362  cut(cut.c_str()), opt(opt.c_str()) {
363  this->container = new TMVA::DataLoader(name);
364  for (std::pair<std::string,char>& p : value->get_label_types()){
365  this->container->AddVariable(p.first, p.second);
366  }
367  }
368 
369  void add_method(const std::string& method_name, const std::string& method_params) {
370  methods.push_back(std::make_pair(method_name, method_params));
371  }
372 
373  void save_as(const std::string& fname, const SaveOption& option = SaveOption::PNG) {
374  TFile* outputFile = gDirectory->GetFile();
375 
376  this->container->PrepareTrainingAndTestTree(cut, opt);
377  TMVA::Factory *factory = new TMVA::Factory("TMVAClassification", outputFile,
378  "!V:!Silent:Color:DrawProgressBar:Transformations=I;D;P;G,D:AnalysisType=Classification");
379 
380  TMVA::Types& types = TMVA::Types::Instance();
381  for(auto& p : methods){
382  std::string method_name, method_params;
383  std::tie(method_name, method_params) = p;
384  TMVA::Types::EMVA method_type = types.GetMethodType(method_name);
385  factory->BookMethod(this->container, method_type, method_name, method_params);
386  }
387 
388  // Train MVAs using the set of training events
389  factory->TrainAllMethods();
390  // Evaluate all MVAs using the set of test events
391  factory->TestAllMethods();
392  // Evaluate and compare performance of all configured MVAs
393  factory->EvaluateAllMethods();
394 
395  delete factory;
396  }
397 };
398 }
399 #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