1 |
#include <iostream>
|
2 |
#include <set>
|
3 |
#include "TChain.h"
|
4 |
#include "TH1.h"
|
5 |
#include "TH2.h"
|
6 |
#include "TFile.h"
|
7 |
|
8 |
// muon info
|
9 |
typedef struct {
|
10 |
int charge;
|
11 |
float pt;
|
12 |
float eta;
|
13 |
float phi;
|
14 |
|
15 |
float normChiSquare;
|
16 |
float d0;
|
17 |
|
18 |
int numValidMuonHits;
|
19 |
int numValidPixelHits;
|
20 |
int numValidTrackerHits;
|
21 |
int numValidStripHits;
|
22 |
int numSegmentMatches;
|
23 |
|
24 |
float trackIsoSumPt;
|
25 |
|
26 |
int isHltMatched;
|
27 |
char hltPath[128];
|
28 |
|
29 |
} _MuonInfo;
|
30 |
|
31 |
// true info
|
32 |
typedef struct {
|
33 |
int charge;
|
34 |
float pt;
|
35 |
float eta;
|
36 |
float phi;
|
37 |
|
38 |
} _TrueInfo;
|
39 |
|
40 |
struct _EventInfo {
|
41 |
Int_t run, lumi, event;
|
42 |
} eventInfo;
|
43 |
|
44 |
bool isLoose(_MuonInfo& muon) {
|
45 |
bool isLoose=false;
|
46 |
|
47 |
// kinematic cuts
|
48 |
if (muon.pt < 20. ) return isLoose; // pt cut
|
49 |
if (fabs(muon.eta) > 2.4) return isLoose; // eta cut
|
50 |
if (muon.numValidTrackerHits < 10) return isLoose; // # hits in tracker
|
51 |
|
52 |
// iso cut
|
53 |
if (muon.trackIsoSumPt>10) return isLoose;
|
54 |
|
55 |
// beam spot cut
|
56 |
if (fabs(muon.d0) > 0.2) return isLoose;
|
57 |
|
58 |
// if all the cuts are passed
|
59 |
isLoose=true;
|
60 |
return isLoose;
|
61 |
}
|
62 |
|
63 |
bool isKinTight(_MuonInfo& muon) {
|
64 |
bool isKinTight=false;
|
65 |
|
66 |
// minimum requirement to start investigating: to be loose
|
67 |
if ( !isLoose(muon) ) return isKinTight;
|
68 |
|
69 |
if ( muon.eta > 2.1 ) return isKinTight;
|
70 |
if ( muon.numValidMuonHits < 1 ) return isKinTight;
|
71 |
if ( muon.numValidPixelHits < 1 ) return isKinTight;
|
72 |
if ( muon.numSegmentMatches < 2 ) return isKinTight;
|
73 |
if ( muon.normChiSquare > 10) return isKinTight;
|
74 |
|
75 |
isKinTight=true;
|
76 |
return isKinTight;
|
77 |
}
|
78 |
|
79 |
double cuts_error = 0;
|
80 |
|
81 |
double cuts(const char *file, double threshold=-1){
|
82 |
TChain *tree = new TChain("tree");
|
83 |
tree->AddFile(file);
|
84 |
//tree->AddFile("../reweighting/tuples/dimuons_run132440to147195.root");
|
85 |
//tree->AddFile("../reweighting/tuples/dimuons_run147196to148058.root");
|
86 |
//tree->AddFile("../reweighting/tuples/dimuons_run148059to149442.root");
|
87 |
|
88 |
tree->SetBranchAddress("eventInfo", &eventInfo);
|
89 |
|
90 |
_MuonInfo reco1, reco2;
|
91 |
|
92 |
tree->SetBranchAddress("reco1", &reco1);
|
93 |
tree->SetBranchAddress("reco2", &reco2);
|
94 |
|
95 |
float recoMass, recoPt;
|
96 |
tree->SetBranchAddress("recoCandMass", &recoMass);
|
97 |
tree->SetBranchAddress("recoCandPt", &recoPt );
|
98 |
|
99 |
_TrueInfo true1, true2;
|
100 |
tree->SetBranchAddress("true1", &true1);
|
101 |
tree->SetBranchAddress("true2", &true2);
|
102 |
|
103 |
float trueMass, truePt;
|
104 |
tree->SetBranchAddress("trueMass", &trueMass);
|
105 |
tree->SetBranchAddress("truePt", &truePt );
|
106 |
|
107 |
TH1F *qT = new TH1F("qT", "", 20000,0,2000.);
|
108 |
TH1F *qTtrue = new TH1F("qTtrue", "", 20000,0,2000.);
|
109 |
|
110 |
const double mLow = 60., mHigh = 120.;
|
111 |
|
112 |
/*
|
113 |
TFile f("boostedZ.root","RECREATE");
|
114 |
TTree skim("skim","skim");
|
115 |
skim.Branch("qT",&recoPt,"qT/F");
|
116 |
tree->AddFile("../reweighting/tuples/dimuons_run132440to147195.root");
|
117 |
tree->AddFile("../reweighting/tuples/dimuons_run147196to148058.root");
|
118 |
tree->AddFile("../reweighting/tuples/dimuons_run148059to149442.root");
|
119 |
tree->SetBranchAddress("recoCandMassCktl", &recoMass);
|
120 |
tree->SetBranchAddress("recoCandPtCktl", &recoPt );
|
121 |
*/
|
122 |
|
123 |
// const int total=5000;
|
124 |
|
125 |
int qT200=0, qT250=0, qT300=0, qT350=0, qT400=0, qT450=0, qT500=0, qT550=0, qT600=0, qT650=0, qTthreshold=0;
|
126 |
int _qT200=0, _qT250=0, _qT300=0, _qT350=0, _qT400=0, _qT450=0, _qT500=0, _qT550=0, _qT600=0, _qT650=0, _qTthreshold=0;
|
127 |
|
128 |
set<int> uniqueEvents, uniqueSelectedEvents;
|
129 |
|
130 |
int event=0, total=0, pass=0, nDuplicates=0;
|
131 |
for(event=0; tree->GetEvent(event) /*&& event<230*/; event++){
|
132 |
// if (true1.charge*true2.charge>0) continue;
|
133 |
|
134 |
// Check combinatorics (different di-muon combinations within the same event; bad for efficiency calculation); pick the first one as truePt is the same for all
|
135 |
if( !uniqueEvents.insert(eventInfo.event).second ){
|
136 |
// cout<<"Duplicate: run="<<eventInfo.run<<" lumi="<<eventInfo.lumi<<" event="<<eventInfo.event<<" recoMass="<<recoMass<<" recoPt="<<recoPt<<" true1.eta="<<true1.eta<<" true2.eta="<<true2.eta<<endl;
|
137 |
nDuplicates++;
|
138 |
} else {
|
139 |
if( truePt>200 ) _qT200++;
|
140 |
if( truePt>250 ) _qT250++;
|
141 |
if( truePt>300 ) _qT300++;
|
142 |
if( truePt>350 ) _qT350++;
|
143 |
if( truePt>400 ) _qT400++;
|
144 |
if( truePt>450 ) _qT450++;
|
145 |
if( truePt>500 ) _qT500++;
|
146 |
if( truePt>550 ) _qT550++;
|
147 |
if( truePt>600 ) _qT600++;
|
148 |
if( truePt>650 ) _qT650++;
|
149 |
if( truePt>threshold ) _qTthreshold++;
|
150 |
total++;
|
151 |
qTtrue->Fill(truePt);
|
152 |
}
|
153 |
|
154 |
// After the following 3 lines of selection we still have ~10% of events with more that 2 muons
|
155 |
if (reco1.charge*reco2.charge>0) continue;
|
156 |
if (recoMass < mLow) continue;
|
157 |
if (recoMass > mHigh) continue;
|
158 |
|
159 |
// kinematical selection efficiency (no trigger)
|
160 |
if( !isLoose(reco1) || !isLoose(reco2) ) continue; // both loose
|
161 |
if( !isKinTight(reco1) && !isKinTight(reco2) ) continue; // at least one tight
|
162 |
|
163 |
// Below we calculate numbers for the cumulative acc x eff x T:
|
164 |
// (if we have duplicates we take all, what are we to do anyway?)
|
165 |
if( !uniqueSelectedEvents.insert(eventInfo.event).second ){
|
166 |
cout<<"Duplicate selected: run="<<eventInfo.run<<" lumi="<<eventInfo.lumi<<" event="<<eventInfo.event<<" recoMass="<<recoMass<<" recoPt="<<recoPt<<endl;
|
167 |
}
|
168 |
if( recoPt>200 ) qT200++;
|
169 |
if( recoPt>250 ) qT250++;
|
170 |
if( recoPt>300 ) qT300++;
|
171 |
if( recoPt>350 ) qT350++;
|
172 |
if( recoPt>400 ) qT400++;
|
173 |
if( recoPt>450 ) qT450++;
|
174 |
if( recoPt>500 ) qT500++;
|
175 |
if( recoPt>550 ) qT550++;
|
176 |
if( recoPt>600 ) qT600++;
|
177 |
if( recoPt>650 ) qT650++;
|
178 |
if( recoPt>threshold ) qTthreshold++;
|
179 |
pass++;
|
180 |
|
181 |
qT->Fill(recoPt);
|
182 |
}
|
183 |
cout<<"Total # of events="<<total<<" pass="<<pass<<" duplicates="<<nDuplicates<<endl;
|
184 |
|
185 |
double eff, uncert;
|
186 |
|
187 |
eff = qT200/double(total); uncert = sqrt(eff*(1-eff)/total);
|
188 |
cout<<"200: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT200<<"/"<<_qT200<<", gpEff="<<qT200/float(_qT200)<<")"<<endl;
|
189 |
eff = qT250/double(total); uncert = sqrt(eff*(1-eff)/total);
|
190 |
cout<<"250: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT250<<"/"<<_qT250<<", gpEff="<<qT250/float(_qT250)<<")"<<endl;
|
191 |
eff = qT300/double(total); uncert = sqrt(eff*(1-eff)/total);
|
192 |
cout<<"300: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT300<<"/"<<_qT300<<", gpEff="<<qT300/float(_qT300)<<")"<<endl;
|
193 |
eff = qT350/double(total); uncert = sqrt(eff*(1-eff)/total);
|
194 |
cout<<"350: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT350<<"/"<<_qT350<<", gpEff="<<qT350/float(_qT350)<<")"<<endl;
|
195 |
eff = qT400/double(total); uncert = sqrt(eff*(1-eff)/total);
|
196 |
cout<<"400: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT400<<"/"<<_qT400<<", gpEff="<<qT400/float(_qT400)<<")"<<endl;
|
197 |
eff = qT450/double(total); uncert = sqrt(eff*(1-eff)/total);
|
198 |
cout<<"450: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT450<<"/"<<_qT450<<", gpEff="<<qT450/float(_qT450)<<")"<<endl;
|
199 |
eff = qT500/double(total); uncert = sqrt(eff*(1-eff)/total);
|
200 |
cout<<"500: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT500<<"/"<<_qT500<<", gpEff="<<qT500/float(_qT500)<<")"<<endl;
|
201 |
eff = qT550/double(total); uncert = sqrt(eff*(1-eff)/total);
|
202 |
cout<<"550: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT550<<"/"<<_qT550<<", gpEff="<<qT550/float(_qT550)<<")"<<endl;
|
203 |
eff = qT600/double(total); uncert = sqrt(eff*(1-eff)/total);
|
204 |
cout<<"600: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT600<<"/"<<_qT600<<", gpEff="<<qT600/float(_qT600)<<")"<<endl;
|
205 |
eff = qT650/double(total); uncert = sqrt(eff*(1-eff)/total);
|
206 |
cout<<"650: eff="<<eff<<" uncert="<<uncert<<" (events="<<qT650<<"/"<<_qT650<<", gpEff="<<qT650/float(_qT650)<<")"<<endl;
|
207 |
|
208 |
eff=qTthreshold/double(total); uncert = sqrt(eff*(1-eff)/total);
|
209 |
cout<<threshold<<": eff="<<eff<<" uncert="<<uncert<<" (events="<<qTthreshold<<")"<<endl;
|
210 |
|
211 |
cuts_error = uncert;
|
212 |
return eff;
|
213 |
}
|