DESY Hbb Analysis Framework
BaseAnalyser.cc
Go to the documentation of this file.
1 // system include files
2 #include "boost/program_options.hpp"
3 #include "boost/algorithm/string.hpp"
4 #include <string>
5 #include <iostream>
6 #include <fstream>
7 #include <vector>
8 #include <stdlib.h>
9 #include "TString.h"
10 //
11 // user include files
13 
14 //
15 // class declaration
16 //
17 
18 using namespace analysis;
19 using namespace analysis::tools;
20 
21 //
22 // constructors and destructor
23 //
25 {
26 }
27 
28 
29 BaseAnalyser::BaseAnalyser(int argc, char * argv[])
30 {
31  TH1::SetDefaultSumw2();
32 
33  exe_ = std::string(argv[0]);
34 
35  // some inits
36  scale_ = -1.;
37  weight_ = 1.;
38  xsection_ = -1.;
39  genpartsanalysis_ = false;
40  genjetsanalysis_ = false;
41 
42  // the heavy stuff
43  config_ = std::make_shared<Config>(argc,argv);
44  analysis_ = std::make_shared<Analysis>(config_->ntuplesList(),config_->eventInfo());
45 
46  // output file
47  if ( config_->outputRoot() != "" )
48  {
49  hout_= std::make_shared<TFile>(config_->outputRoot().c_str(),"recreate",Form("%s %s %s",argv[0],argv[1],argv[2]));
50  hout_ -> cd();
51  }
52 
53  seed_ = analysis_ ->seed(config_->seedFile());
54 
55  // Workflow
56  h1_["cutflow"] = std::make_shared<TH1F>("workflow",Form("Workflow #%d",config_->workflow()), 100,0,100);
57 
58 
59  isMC_ = analysis_->isMC();
60  isData_ = !isMC_;
61 
62  // Some MC-only stuff
63  if ( isMC_ )
64  {
65  // Cross sections
66  if ( analysis_ -> crossSections(config_->crossSectionTree()) == 0 )
67  xsection_ = analysis_->crossSection(config_->crossSectionType());
68  // Pileup weights
69  if ( config_->pileupWeights() != "" )
70  {
71  puweights_ = analysis_->pileupWeights(config_->pileupWeights());
72  puw_label_ = basename(config_->pileupWeights());
73  }
74  else
75  {
76  puw_label_ = "*** missing *** assuming puweight = 1";
77  }
78 
79  // gen part analysis
80  genpartsanalysis_ = ( analysis_->addTree<GenParticle> ("GenParticles",config_->genParticlesCollection()) != nullptr );
81  // gen jets analysis
82  genjetsanalysis_ = ( analysis_->addTree<GenJet> ("GenJets",config_->genJetsCollection()) != nullptr );
83 
84  }
85 
86  // JSON for data
87  if( isData_ && config_->json() != "" ) analysis_->processJsonFile(config_->json());
88 
89  // btag efficiencies
90  if ( config_->btagEfficiencies() != "" )
91  {
92  TFile f(config_->btagEfficiencies().c_str(),"old");
93  auto list = f.GetListOfKeys();
94  for ( int i = 0; i < list -> GetSize(); ++i)
95  {
96  TString item(list -> At(i) -> GetName());
97  if ( ! item.BeginsWith("eff_")) continue;
98  item.Remove(0,4);
99  btageff_[item.Data()] = std::shared_ptr<TGraphAsymmErrors>((TGraphAsymmErrors*)f.Get(("eff_"+item).Data()));
100  }
101  f.Close();
102  }
103 
104 }
105 
107 {
108  std::cout << std::endl;
109  // get last bin
110  int lastbin = 0;
111  for ( int i = 1; i <= h1_["cutflow"] ->GetNbinsX(); ++i )
112  {
113  std::string label = std::string(h1_["cutflow"]->GetXaxis()->GetBinLabel(i));
114  if ( label == "" )
115  {
116  lastbin = i-1;
117  break;
118  }
119  }
120  float fevts = h1_["cutflow"] -> GetBinContent(lastbin);
121  // overall scale
122  float scale = 1.;
123  bool doscale = false;
124  if ( scale_ > 0. ) // superseeds the scale from config
125  {
126  doscale = true;
127  scale = scale_;
128  }
129  else
130  {
131  // scale from config
132  if ( config_ -> scale() > 0. )
133  {
134  doscale = true;
135  scale = config_ -> scale();
136  }
137  }
138  if ( doscale )
139  {
140  if ( std::string(h1_["cutflow"] -> GetXaxis()-> GetBinLabel(lastbin+1)) == "" )
141  {
142  h1_["cutflow"] -> GetXaxis()-> SetBinLabel(lastbin+1,Form("Number of events after scaling to %10.5f",scale));
143  }
144  h1_["cutflow"] -> Fill(lastbin,fevts*scale);
145  }
146 
147 
148  for ( auto h : h1_ )
149  {
150  if ( h.first == "cutflow" || h.first == "pileup" || h.first == "pileup_w" ) continue;
151  if ( doscale ) h.second -> Scale(scale);
152  bool is_empty = ( h.second -> GetEntries() != 0 || h.second -> GetSumOfWeights() != 0 );
153  if ( is_empty )
154  continue;
155 
156  }
157  for ( auto h : h2_ )
158  {
159  if ( doscale ) h.second -> Scale(scale);
160  bool is_empty = ( h.second -> GetEntries() != 0 || h.second -> GetSumOfWeights() != 0 );
161  if ( is_empty ) continue;
162  }
163 
164  if ( hout_ )
165  {
166 // std::cout << std::endl;
167 // std::cout << "output root file: " << config_->outputRoot() << std::endl;
168  hout_ -> cd();
169  hout_ -> Write();
170  hout_->Close();
171  // print workflow using the Workflow macro
172  try
173  {
174  system(Form("Workflow %s",config_->outputRoot().c_str()));
175  }
176  catch(...)
177  {
178  std::cout << "Problems with Workflow macro or the output file, no summary printed" << std::endl;
179  }
180  }
181 
182  std::cout << std::endl;
183  std::cout << exe_ << " finished!" << std::endl;
184  printf("%s\n", std::string(100,'_').c_str());
185  std::cout << std::endl;
186 
187  std::ofstream finished;
188  finished.open("finished.txt");
189  finished << exe_ << "\n";
190  finished.close();
191 
192 }
193 
194 
195 //
196 // member functions
197 //
198 // ------------ method called for each event ------------
199 
200 bool BaseAnalyser::event(const int & i) { return true; }
201 void BaseAnalyser::histograms(const std::string & s, const int & i) { }
202 
203 std::shared_ptr<Analysis> BaseAnalyser::analysis()
204 {
205  return analysis_;
206 }
207 
208 std::shared_ptr<Config> BaseAnalyser::config()
209 {
210  return config_;
211 }
212 
214 {
215  int maxevt = config_->nEventsMax();
216  if ( maxevt < 0 || maxevt > analysis_->size() ) maxevt = analysis_->size();
217  return maxevt;
218 }
219 
220 std::shared_ptr<TH1F> BaseAnalyser::histogram(const std::string & hname)
221 {
222  if ( h1_.find(hname) == h1_.end() )
223  {
224  std::cout << "-e- BaseAnalyser::H1F(const string & hname) -> no histogram with hname = " << hname << std::endl;
225  return nullptr;
226  }
227 
228  return h1_[hname];
229 }
230 
231 std::map<std::string, std::shared_ptr<TH1F> > BaseAnalyser::histograms()
232 {
233  return h1_;
234 }
235 
236 
238 {
239  return seed_;
240 }
241 
242 int BaseAnalyser::seed(const std::string & f)
243 {
244  seed_ = analysis_ ->seed(f);
245  return seed_;
246 }
247 
248 void BaseAnalyser::seed(const int & seed)
249 {
250  seed_ = seed;
251 }
252 
253 void BaseAnalyser::weight(const float & w)
254 {
255  weight_ = w;
256 }
257 
259 {
260  return weight_;
261 }
262 
263 std::shared_ptr<TFile> BaseAnalyser::output()
264 {
265  return hout_;
266 }
267 
269 {
270  return genpartsanalysis_;
271 }
272 
274 {
275  return genjetsanalysis_;
276 }
277 
279 {
280  return xsection_;
281 }
282 
283 std::shared_ptr<PileupWeight> BaseAnalyser::pileupWeights() const
284 {
285  return puweights_;
286 }
287 
288 float BaseAnalyser::pileupWeight(const float & truepu, const int & var) const
289 {
290  if ( ! puweights_ ) return 1.;
291  return puweights_->weight(truepu,var);
292 }
293 
295 {
296  if ( ! config_->isMC() ) return -1;
297 
298  return float(analysis_->nTruePileup());
299 }
300 
302 {
303  if ( ! config_->isMC() ) return;
304 
305  if ( puweights_ )
306  weight_ *= this->pileupWeight(analysis_->nTruePileup(),var);
307  else
308  weight_ *= 1;
309 
311 
312  this -> fillPileupHistogram();
313 }
314 
316 {
317  this->output()->cd();
318  if ( config_->min() > 0 && config_->max() > 0 )
319  {
320  h1_["pileup"] = std::make_shared<TH1F>("pileup" , "pileup" , config_->n() , config_->min() , config_->max() );
321  h1_["pileup_w"] = std::make_shared<TH1F>("pileup_w" , "weighted pileup" , config_->n() , config_->min() , config_->max() );
322  }
323  else
324  {
325  h1_["pileup"] = std::make_shared<TH1F>("pileup" , "pileup" , 100 , 0 , 100 );
326  h1_["pileup_w"] = std::make_shared<TH1F>("pileup_w" , "weighted pileup" , 100 , 0 , 100 );
327  }
328 
329 }
331 {
332 
333  h1_["pileup"] -> Fill(analysis_->nTruePileup());
334  h1_["pileup_w"] -> Fill(analysis_->nTruePileup(),this->pileupWeight(analysis_->nTruePileup(),0));
335 }
336 
338 {
339  return cutflow_;
340 }
341 
342 void BaseAnalyser::cutflow(const int & c)
343 {
344  cutflow_ = c;
345 }
346 
347 void BaseAnalyser::cutflow(const std::string & label, const bool & ok)
348 {
349  ++cutflow_;
350  if ( std::string(h1_["cutflow"] -> GetXaxis()-> GetBinLabel(cutflow_+1)) == "" )
351  {
352  h1_["cutflow"] -> GetXaxis()-> SetBinLabel(cutflow_+1,label.c_str());
353  }
354  if ( ok ) h1_["cutflow"] -> Fill(cutflow_,weight_);
355 
356 }
357 
358 void BaseAnalyser::scale(const float & scale)
359 {
360  scale_ = scale;
361 }
362 
363 std::string BaseAnalyser::basename(const std::string & name)
364 {
365  std::string bn = "";
366  std::vector<std::string> paths;
367  if ( name != "" )
368  {
369  boost::split(paths, name, boost::is_any_of("/"));
370  bn = paths.back();
371  }
372  return bn;
373 
374 
375 }
376 
377 std::map<std::string, std::shared_ptr<TGraphAsymmErrors> > BaseAnalyser::btagEfficiencies() const
378 {
379  return btageff_;
380 }
381 
382 
384 {
385  if ( ! config_->isMC() ) return;
386 
387  float weight = analysis_->genWeight();
388  if ( config_->fullGenWeight() )
389  {
390  weight_ *= weight;
391  }
392  else
393  {
394  float sign = (weight > 0) ? 1 : ((weight < 0) ? -1 : 0);
395  weight_ *= sign;
396  }
397 
398 }
399 
400 bool BaseAnalyser::triggerEmulation(const std::string & name, const int & nmin, const float & ptmin, const float & etamax, const std::string & newname)
401 {
402  trg_emul_[newname] = true;
403  std::vector<TriggerObject> new_objects;
404 
405 
406  if ( name != "l1tJets" && name != "l1tMuons" )
407  {
408  std::shared_ptr< Collection<TriggerObject> > objects = analysis_->collection<TriggerObject>(name);
409 
410  for ( int i = 0 ; i < objects->size() ; ++i )
411  {
412  TriggerObject obj = objects->at(i);
413  if ( obj.pt() >= ptmin && fabs(obj.eta()) <= etamax )
414  {
415  new_objects.push_back(obj);
416  }
417  }
418 
419  }
420 
421  if ( name == "l1tJets" )
422  {
423  std::shared_ptr< Collection<L1TJet> > l1tjets = analysis_->collection<L1TJet>(name);
424 
425  for ( int i = 0 ; i < l1tjets->size() ; ++i )
426  {
427  L1TJet l1tjet = l1tjets -> at(i);
428  float pt = l1tjet.pt();
429  float eta = l1tjet.eta();
430  float phi = l1tjet.phi();
431  float e = l1tjet.e();
432  TriggerObject obj(pt,eta,phi,e);
433  if ( obj.pt() >= ptmin && fabs(obj.eta()) <= etamax )
434  {
435  new_objects.push_back(obj);
436  }
437  }
438 
439  }
440  if ( name == "l1tMuons" )
441  {
442  std::shared_ptr< Collection<L1TMuon> > l1tmuons = analysis_->collection<L1TMuon>(name);
443 
444  for ( int i = 0 ; i < l1tmuons->size() ; ++i )
445  {
446  L1TMuon l1tmuon = l1tmuons -> at(i);
447  float pt = l1tmuon.pt();
448  float eta = l1tmuon.eta();
449  float phi = l1tmuon.phi();
450  float e = l1tmuon.e();
451  TriggerObject obj(pt,eta,phi,e);
452  if ( obj.pt() >= ptmin && fabs(obj.eta()) <= etamax )
453  {
454  new_objects.push_back(obj);
455  }
456  }
457 
458  }
459  trg_emul_[newname] = ( (int)new_objects.size() >= nmin );
460 
461  Collection<TriggerObject> new_collection(new_objects,newname);
462  analysis_->addCollection(new_collection);
463 
464  return trg_emul_[newname];
465 
466 
467 
468 }
469 
470 
471 std::map<std::string,bool> BaseAnalyser::triggersEmulated()
472 {
473  return trg_emul_;
474 }
475 
476 bool BaseAnalyser::triggerEmulated(const std::string & name)
477 {
478  return trg_emul_[name];
479 }
bool isData_
flag for DATA sample
Definition: BaseAnalyser.h:104
virtual bool event(const int &)
event entry to be readout and processed
float crossSection() const
returns cross section
int cutflow()
get cutflow index
float eta() const
returns the pseudorapidity
Definition: Candidate.cc:134
std::string exe_
name of the executable
Definition: BaseAnalyser.h:116
virtual ~BaseAnalyser()
desctructor
std::shared_ptr< TH1F > histogram(const std::string &)
returns a given 1D histogram
std::shared_ptr< Config > config()
returns pointer to Config object
void actionApplyPileupWeight(const int &var=0)
apply pileup weight given a systematic variation
void pileupHistogram()
creates pileup histogram
std::shared_ptr< TFile > output()
returns pointer to output root file
std::shared_ptr< PileupWeight > pileupWeights() const
returns pointer to pileup weights (MC-only)
std::map< std::string, bool > trg_emul_
emulated triggers
Definition: BaseAnalyser.h:110
void fillPileupHistogram()
fills pileup histogram
TH1F * h[10]
Definition: PlotsCompare.cc:25
float e() const
returns the energy
Definition: Candidate.cc:136
bool genParticlesAnalysis() const
returns whether analysis of gen particles can be done
std::shared_ptr< PileupWeight > puweights_
pileup weight
Definition: BaseAnalyser.h:90
std::map< std::string, std::shared_ptr< TGraphAsymmErrors > > btagEfficiencies() const
bool isMC_
flag for MC sample
Definition: BaseAnalyser.h:102
bool genJetsAnalysis() const
returns whether analysis of gen jets can be done
std::string basename(const std::string &)
returns the basename of a path
std::shared_ptr< Config > config_
Config objects.
Definition: BaseAnalyser.h:63
std::shared_ptr< TFile > hout_
output root file
Definition: BaseAnalyser.h:78
float phi() const
returns the azimuthal angle
Definition: Candidate.cc:135
void generatorWeight()
generator weight
std::shared_ptr< Analysis > analysis_
Analysis objects.
Definition: BaseAnalyser.h:61
float pileupWeight(const float &truepu, const int &var) const
returns pileup weight given the true pileup and uncertainty variation in values of sigma ...
std::map< std::string, std::shared_ptr< TGraphAsymmErrors > > btageff_
Definition: BaseAnalyser.h:84
int seed()
returns a seed for random number generator
std::string puw_label_
pileup weight label
Definition: BaseAnalyser.h:93
std::map< std::string, std::shared_ptr< TH1F > > histograms()
returns all 1D histograms
float trueInteractions() const
returns true number of interactions
float weight_
event weight
Definition: BaseAnalyser.h:72
std::map< std::string, bool > triggersEmulated()
return status of all emulated l1 triggers
float pt() const
returns the transverse momentum
Definition: Candidate.cc:133
void scale(const float &)
sets a scale
bool triggerEmulated(const std::string &)
return status of an emulated l1 trigger
std::map< std::string, std::shared_ptr< TH1F > > h1_
1D histograms mapping
Definition: BaseAnalyser.h:80
float xsection_
cross section
Definition: BaseAnalyser.h:75
int cutflow_
Cutflow index.
Definition: BaseAnalyser.h:66
float scale_
overall scaling
Definition: BaseAnalyser.h:99
TFile * f[10]
Definition: PlotsCompare.cc:24
std::shared_ptr< Analysis > analysis()
returns pointer to Analysis object
int nEvents()
number of events to be processed
virtual bool triggerEmulation(const std::string &, const int &, const float &, const float &, const std::string &)
emulate l1 trigger
float weight()
returns event weight
std::map< std::string, std::shared_ptr< TH2F > > h2_
2D histograms mapping
Definition: BaseAnalyser.h:82