DESY Hbb Analysis Framework
SimpleMssmHbbAnalysis.cc
Go to the documentation of this file.
1 #include "boost/program_options.hpp"
2 #include "boost/algorithm/string.hpp"
3 #include <string>
4 #include <iostream>
5 #include <fstream>
6 #include <vector>
7 
8 #include "TFile.h"
9 #include "TFileCollection.h"
10 #include "TChain.h"
11 #include "TH1.h"
12 
15 
16 using namespace std;
17 using namespace analysis;
18 using namespace analysis::tools;
19 
20 // =============================================================================================
21 int main(int argc, char * argv[])
22 {
23 
24  if ( macro_config(argc, argv) != 0 ) return -1;
25 
26  TH1::SetDefaultSumw2(); // proper treatment of errors when scaling histograms
27 
28  // Cuts
29  float btagmin[3] = { btagwptight_, btagwptight_, btagwptight_};
30 
31  // Input files list
33 
34  analysis.addTree<Jet> ("Jets","MssmHbb/Events/slimmedJetsPuppi");
35 
36  for ( auto & obj : triggerObjects_ )
37  {
38  analysis.addTree<TriggerObject> (obj,Form("MssmHbb/Events/slimmedPatTrigger/%s",obj.c_str()));
39  }
40 
41  analysis.triggerResults("MssmHbb/Events/TriggerResults");
42 
43  if( !isMC_ )
44  {
45  int json_status = analysis.processJsonFile(json_);
46  if ( json_status < 0 )
47  {
48  std::cout << "Error from processing json. Please check your json file." << std::endl;
49  return -1;
50  }
51  }
52 
53  std::string sr_s = "SR";
54  if ( ! signalregion_ ) sr_s = "CR";
55  boost::algorithm::replace_last(outputRoot_, ".root", "_"+sr_s+".root");
56 
57  TFile hout(outputRoot_.c_str(),"recreate");
58 
59  std::map<std::string, TH1F*> h1;
60  h1["n"] = new TH1F("n" , "" , 30, 0, 30);
61  h1["n_csv"] = new TH1F("n_csv" , "" , 30, 0, 30);
62  h1["n_ptmin20"]= new TH1F("n_ptmin20" , "" , 30, 0, 30);
63  h1["n_ptmin20_csv"] = new TH1F("n_ptmin20_csv" , "" , 30, 0, 30);
64  for ( int i = 0 ; i < njetsmin_ ; ++i )
65  {
66  h1[Form("pt_%i",i)] = new TH1F(Form("pt_%i",i) , "" , 100, 0, 1000);
67  h1[Form("eta_%i",i)] = new TH1F(Form("eta_%i",i) , "" , 100, -5, 5);
68  h1[Form("phi_%i",i)] = new TH1F(Form("phi_%i",i) , "" , 100, -4, 4);
69  h1[Form("btag_%i",i)] = new TH1F(Form("btag_%i",i) , "" , 500, 0, 1);
70 
71  h1[Form("pt_%i_csv",i)] = new TH1F(Form("pt_%i_csv",i) , "" , 100, 0, 1000);
72  h1[Form("eta_%i_csv",i)] = new TH1F(Form("eta_%i_csv",i) , "" , 100, -5, 5);
73  h1[Form("phi_%i_csv",i)] = new TH1F(Form("phi_%i_csv",i) , "" , 100, -4, 4);
74  h1[Form("btag_%i_csv",i)] = new TH1F(Form("btag_%i_csv",i) , "" , 500, 0, 1);
75  }
76  h1["m12"] = new TH1F("m12" , "" , 50, 0, 1000);
77  h1["m12_csv"] = new TH1F("m12_csv" , "" , 50, 0, 1000);
78 
79 
80  double mbb;
81  double weight;
82  TTree *tree = new TTree("MssmHbb_13TeV","");
83  tree->Branch("mbb",&mbb,"mbb/D");
84  tree->Branch("weight",&weight,"weight/D");
85 
86  // Analysis of events
87  std::cout << "This analysis has " << analysis.size() << " events" << std::endl;
88 
89  // Cut flow
90  // 0: triggered events
91  // 1: 3+ idloose jets
92  // 2: kinematics
93  // 3: matched to online
94  // 4: delta R
95  // 5: delta eta
96  // 6: btag (bbnb)
97  int nsel[10] = { };
98  int nmatch[10] = { };
99 
100  if ( nevtmax_ < 0 ) nevtmax_ = analysis.size();
101  for ( int i = 0 ; i < nevtmax_ ; ++i )
102  {
103  int njets = 0;
104  int njets_csv = 0;
105  bool goodEvent = true;
106 
107  if ( i > 0 && i%100000==0 ) std::cout << i << " events processed! " << std::endl;
108 
109  analysis.event(i);
110  if (! isMC_ )
111  {
112  if (!analysis.selectJson() ) continue; // To use only goodJSonFiles
113  }
114 
115  int triggerFired = analysis.triggerResult(hltPath_);
116  if ( !triggerFired ) continue;
117 
118  ++nsel[0];
119 
120  // match offline to online
121  analysis.match<Jet,TriggerObject>("Jets",triggerObjects_,0.5);
122 
123  // Jets - std::shared_ptr< Collection<Jet> >
124  auto slimmedJets = analysis.collection<Jet>("Jets");
125  std::vector<Jet *> selectedJets;
126  for ( int j = 0 ; j < slimmedJets->size() ; ++j )
127  {
128  if ( slimmedJets->at(j).idLoose() ) selectedJets.push_back(&slimmedJets->at(j));
129  }
130  if ( (int)selectedJets.size() < njetsmin_ ) continue;
131 
132  ++nsel[1];
133 
134  // Kinematic selection - 3 leading jets
135  for ( int j = 0; j < njetsmin_; ++j )
136  {
137  Jet * jet = selectedJets[j];
138  if ( jet->pt() < jetsptmin_[j] || fabs(jet->eta()) > jetsetamax_[j] )
139  {
140  goodEvent = false;
141  break;
142  }
143  }
144 
145  if ( ! goodEvent ) continue;
146 
147  ++nsel[2];
148 
149  for ( int j1 = 0; j1 < njetsmin_-1; ++j1 )
150  {
151  const Jet & jet1 = *selectedJets[j1];
152  for ( int j2 = j1+1; j2 < njetsmin_; ++j2 )
153  {
154  const Jet & jet2 = *selectedJets[j2];
155  if ( jet1.deltaR(jet2) < drmin_ ) goodEvent = false;
156  }
157  }
158 
159  if ( ! goodEvent ) continue;
160 
161  ++nsel[3];
162 
163  if ( fabs(selectedJets[0]->eta() - selectedJets[1]->eta()) > detamax_ ) continue;
164 
165  ++nsel[4];
166 
167 
168  // Fill histograms of kinematic passed events
169  for ( int j = 0 ; j < (int)selectedJets.size() ; ++j )
170  {
171  if ( selectedJets[j]->pt() < 20. ) continue;
172  ++njets;
173  }
174 
175  h1["n"] -> Fill(selectedJets.size());
176  h1["n_ptmin20"] -> Fill(njets);
177  for ( int j = 0; j < njetsmin_; ++j )
178  {
179  Jet * jet = selectedJets[j];
180  h1[Form("pt_%i",j)] -> Fill(jet->pt());
181  h1[Form("eta_%i",j)] -> Fill(jet->eta());
182  h1[Form("phi_%i",j)] -> Fill(jet->phi());
183  h1[Form("btag_%i",j)] -> Fill(jet->btag("btag_csvivf"));
184 
185  if ( j < 2 && jet->btag("btag_csvivf") < btagmin[j] ) goodEvent = false;
186  if ( ! signalregion_ )
187  {
188  if ( j == 2 && jet->btag("btag_csvivf") > nonbtagwp_ ) goodEvent = false;
189  }
190  else
191  {
192  if ( j == 2 && jet->btag("btag_csvivf") < btagmin[j] ) goodEvent = false;
193  }
194  }
195 
196  h1["m12"] -> Fill((selectedJets[0]->p4() + selectedJets[1]->p4()).M());
197 
198  if ( ! goodEvent ) continue;
199 
200  ++nsel[5];
201 
202 // std::cout << "oioi" << std::endl;
203 
204 
205  // Is matched?
206  bool matched[10] = {true,true,true,true,true,true,true,true,true,true};
207  for ( int j = 0; j < 2; ++j )
208  {
209  Jet * jet = selectedJets[j];
210 // for ( auto & obj : triggerObjects_ ) matched = (matched && jet->matched(obj));
211  for ( size_t io = 0; io < triggerObjects_.size() ; ++io )
212  {
213  if ( ! jet->matched(triggerObjects_[io]) ) matched[io] = false;
214  }
215  }
216 
217  for ( size_t io = 0; io < triggerObjects_.size() ; ++io )
218  {
219  if ( matched[io] ) ++nmatch[io];
220  goodEvent = ( goodEvent && matched[io] );
221  }
222 
223  if ( ! goodEvent ) continue;
224 
225  ++nsel[6];
226 
227  // Fill histograms of passed bbnb btagging selection
228  for ( int j = 0 ; j < (int)selectedJets.size() ; ++j )
229  {
230  if ( selectedJets[j]->pt() < 20. ) continue;
231  ++njets_csv;
232  }
233  h1["n_csv"] -> Fill(selectedJets.size());
234  h1["n_ptmin20_csv"] -> Fill(njets_csv);
235  for ( int j = 0; j < njetsmin_; ++j )
236  {
237  Jet * jet = selectedJets[j];
238  h1[Form("pt_%i_csv",j)] -> Fill(jet->pt());
239  h1[Form("eta_%i_csv",j)] -> Fill(jet->eta());
240  h1[Form("phi_%i_csv",j)] -> Fill(jet->phi());
241  h1[Form("btag_%i_csv",j)] -> Fill(jet->btag("btag_csvivf"));
242  }
243  mbb = (selectedJets[0]->p4() + selectedJets[1]->p4()).M();
244  if ( !signalregion_ )
245  {
246  h1["m12_csv"] -> Fill(mbb);
247  weight = 1;
248  tree -> Fill();
249  }
250 
251  }
252 
253  for (auto & ih1 : h1)
254  {
255  ih1.second -> Write();
256  }
257 
258  hout.Write();
259  hout.Close();
260 
261 // PRINT OUTS
262 
263  // Cut flow
264  // 0: triggered events
265  // 1: 3+ idloose jets
266  // 2: matched to online
267  // 3: kinematics
268  // 4: delta R
269  // 5: delta eta
270  // 6: btag (bbnb)
271 
272  double fracAbs[10];
273  double fracRel[10];
274  std::string cuts[10];
275  cuts[0] = "Triggered";
276  cuts[1] = "Triple idloose-jet";
277  cuts[2] = "Triple jet kinematics";
278  cuts[3] = "Delta R(i;j)";
279  cuts[4] = "Delta eta(j1;j2)";
280  cuts[5] = "btagged (bbnb)";
281  if ( signalregion_ ) cuts[5] = "btagged (bbb)";
282  cuts[6] = "Matched to online j1;j2";
283 
284  printf ("%-23s %10s %10s %10s \n", std::string("Cut flow").c_str(), std::string("# events").c_str(), std::string("absolute").c_str(), std::string("relative").c_str() );
285  for ( int i = 0; i < 7; ++i )
286  {
287  fracAbs[i] = double(nsel[i])/nsel[0];
288  if ( i>0 )
289  fracRel[i] = double(nsel[i])/nsel[i-1];
290  else
291  fracRel[i] = fracAbs[i];
292  printf ("%-23s %10d %10.3f %10.3f \n", cuts[i].c_str(), nsel[i], fracAbs[i], fracRel[i] );
293  }
294  // CSV output
295  printf ("%-23s , %10s , %10s , %10s \n", std::string("Cut flow").c_str(), std::string("# events").c_str(), std::string("absolute").c_str(), std::string("relative").c_str() );
296  for ( int i = 0; i < 7; ++i )
297  printf ("%-23s , %10d , %10.3f , %10.3f \n", cuts[i].c_str(), nsel[i], fracAbs[i], fracRel[i] );
298 
299  // Trigger objects counts
300  std::cout << std::endl;
301  printf ("%-40s %10s \n", std::string("Trigger object").c_str(), std::string("# events").c_str() );
302 // for ( size_t io = 0; io < triggerObjects_.size() ; ++io )
303 // {
304 // printf ("%-40s %10d \n", triggerObjects_[io].c_str(), nmatch[io] );
305 // }
306 
307 
308 
309 
310 
311 
312 } //end main
313 
void match(const std::string &collection, const std::string &match_collection, const float &deltaR=0.5)
Definition: Analysis.h:343
std::shared_ptr< Collection< Object > > collection(const std::string &unique_name)
Definition: Analysis.h:336
float eta() const
returns the pseudorapidity
Definition: Candidate.cc:134
std::vector< float > jetsetamax_
Definition: macro_config.h:54
int macro_config(int argc, char *argv[])
Definition: macro_config.h:145
std::string json_
Definition: macro_config.h:23
int njetsmin_
Definition: macro_config.h:49
float phi() const
returns the azimuthal angle
Definition: Candidate.cc:135
float detamax_
Definition: macro_config.h:101
bool isMC_
Definition: macro_config.h:19
const Candidate * matched(const std::string &name)
returns the pointer to the matched candidate object
Definition: Candidate.cc:147
int processJsonFile(const std::string &fileName="goodJson.txt")
Definition: Analysis.cc:378
bool triggerResult(const std::string &trig)
Definition: Analysis.cc:190
std::string inputlist_
Definition: macro_config.h:21
float pt() const
returns the transverse momentum
Definition: Candidate.cc:133
bool triggerResults(const std::string &path)
Definition: Analysis.cc:162
std::vector< float > jetsptmin_
Definition: macro_config.h:52
float deltaR(const Candidate &) const
returns the deltaR between this and another candidate
Definition: Candidate.cc:140
std::string hltPath_
Definition: macro_config.h:115
void event(const int &event, const bool &addCollections=true)
Definition: Analysis.cc:94
bool signalregion_
Definition: macro_config.h:20
std::shared_ptr< PhysicsObjectTree< Object > > addTree(const std::string &unique_name, const std::string &path)
Definition: Analysis.h:273
std::vector< std::string > triggerObjects_
Definition: macro_config.h:119
int main(int argc, char *argv[])
int nevtmax_
Definition: macro_config.h:15
float btag(const std::string &) const
returns the btag value of btag_csvivf
Definition: Jet.cc:57
float drmin_
Definition: macro_config.h:99
std::string outputRoot_
Definition: macro_config.h:22
float btagwptight_
Definition: macro_config.h:110
float nonbtagwp_
Definition: macro_config.h:112