1 |
|
#include "OSUT3Analysis/AnaTools/interface/OSUAnalysis.h" |
2 |
|
|
3 |
|
OSUAnalysis::OSUAnalysis (const edm::ParameterSet &cfg) : |
4 |
< |
// Retrieve parameters from the configuration file |
4 |
> |
// Retrieve parameters from the configuration file. |
5 |
|
muons_ (cfg.getParameter<edm::InputTag> ("muons")), |
6 |
< |
maxEta_ (cfg.getParameter<double> ("maxEta")), |
7 |
< |
minPt_ (cfg.getParameter<double> ("minPt")) |
6 |
> |
muonCfg_ (cfg.getParameter<edm::ParameterSet> ("muonCfg")) |
7 |
|
{ |
8 |
< |
// Register cut names |
9 |
< |
cutNames_.push_back ("minMuons"); |
8 |
> |
// Construct CutFlow objects. These store the results of cut decisions and |
9 |
> |
// handle filling cut flow histograms. |
10 |
> |
cuts_ = new CutFlow (fs_); |
11 |
> |
muonCuts_ = new CutFlow (fs_, "muon"); |
12 |
|
|
13 |
< |
// Create additional histograms |
14 |
< |
hists1D_["muonPT"] = fs_->make<TH1D> ("muonPt", ";p_{T} (GeV/c)", 100, 0.0, 300.0); |
14 |
< |
hists1D_["muonEta"] = fs_->make<TH1D> ("muonEta", ";#eta", 100, -3.0, 3.0); |
13 |
> |
// Create additional histograms. |
14 |
> |
TH1::SetDefaultSumw2 (); |
15 |
|
hists1D_["muonPhi"] = fs_->make<TH1D> ("muonPhi", ";#phi", 100, -5.0, 5.0); |
16 |
+ |
hists1D_["muonEta"] = fs_->make<TH1D> ("muonEta", ";#eta", 100, -3.0, 3.0); |
17 |
+ |
hists1D_["muonPt"] = fs_->make<TH1D> ("muonPt", ";p_{T} (GeV/c)", 100, 0.0, 300.0); |
18 |
|
hists1D_["dimuonMass"] = fs_->make<TH1D> ("dimuonMass", ";m_{#mu^{+} #mu^{-}} (GeV/c^{2})", 90, 30.0, 120.0); |
17 |
– |
|
18 |
– |
TH1::SetDefaultSumw2 (); |
19 |
– |
hists1D_["cutFlow"] = fs_->make<TH1D> ("cutFlow", "", cutNames_.size () + 1, 0.0, cutNames_.size () + 1); |
20 |
– |
hists1D_["selection"] = fs_->make<TH1D> ("selection", "", cutNames_.size () + 1, 0.0, cutNames_.size () + 1); |
21 |
– |
hists1D_["complementarySelection"] = fs_->make<TH1D> ("complementarySelection", "", cutNames_.size () + 1, 0.0, cutNames_.size () + 1); |
22 |
– |
|
23 |
– |
hists1D_["cutFlow"]->GetXaxis ()->SetBinLabel (1, "Total Events"); |
24 |
– |
hists1D_["selection"]->GetXaxis ()->SetBinLabel (1, "Total Events"); |
25 |
– |
hists1D_["complementarySelection"]->GetXaxis ()->SetBinLabel (1, "Total Events"); |
26 |
– |
for (vector<string>::const_iterator cut = cutNames_.begin (); cut != cutNames_.end (); cut++) |
27 |
– |
{ |
28 |
– |
hists1D_["cutFlow"]->GetXaxis ()->SetBinLabel (cut - cutNames_.begin () + 2, cut->c_str ()); |
29 |
– |
hists1D_["selection"]->GetXaxis ()->SetBinLabel (cut - cutNames_.begin () + 2, cut->c_str ()); |
30 |
– |
hists1D_["complementarySelection"]->GetXaxis ()->SetBinLabel (cut - cutNames_.begin () + 2, cut->c_str ()); |
31 |
– |
} |
19 |
|
} |
20 |
|
|
21 |
< |
void |
35 |
< |
OSUAnalysis::beginJob () |
21 |
> |
OSUAnalysis::~OSUAnalysis () |
22 |
|
{ |
23 |
< |
sw_.Start (); |
24 |
< |
} |
25 |
< |
|
26 |
< |
void |
41 |
< |
OSUAnalysis::endJob () |
42 |
< |
{ |
43 |
< |
sw_.Stop (); |
44 |
< |
outputTime (); |
45 |
< |
outputCutFlow (); |
23 |
> |
// Destroying the CutFlow objects causes the cut flow numbers and time |
24 |
> |
// information to be printed to standard output. |
25 |
> |
delete cuts_; |
26 |
> |
delete muonCuts_; |
27 |
|
} |
28 |
|
|
29 |
|
void |
30 |
|
OSUAnalysis::analyze (const edm::Event &event, const edm::EventSetup &setup) |
31 |
|
{ |
32 |
< |
// Retrieve necessary collections from the event |
32 |
> |
// Retrieve necessary collections from the event. |
33 |
|
edm::Handle<BNmuonCollection> muons; |
34 |
|
event.getByLabel (muons_, muons); |
35 |
|
|
36 |
< |
// Perform selection on objects within the event |
37 |
< |
vector<BNmuonCollection::const_iterator> goodMuons; |
38 |
< |
selectGoodMuons (muons, goodMuons); |
39 |
< |
|
40 |
< |
// Perform selection calculations and store the results in the map cuts_. The |
41 |
< |
// keys to cuts_ must match the strings in cutNames_ |
42 |
< |
cuts_["minMuons"] = goodMuons.size () >= 2; |
36 |
> |
// Perform selection on objects within the event while filling the cut flow |
37 |
> |
// object specific to this collection. |
38 |
> |
GoodMuonCollection goodMuons (muonCfg_, muons, muonCuts_); |
39 |
> |
|
40 |
> |
// Calculate cut decisions and store the results in the CutFlow object, just |
41 |
> |
// like a map. |
42 |
> |
cuts_->at ("maxEta") = goodMuons.goodEtaSize () > 1; |
43 |
> |
cuts_->at ("minPt") = goodMuons.goodPtSize () > 1; |
44 |
> |
cuts_->at ("oppositeSign") = goodMuons.goodSize () > 1 && goodMuons.leadMuon ()->charge * goodMuons.nextToLeadMuon ()->charge < 0; |
45 |
|
|
46 |
< |
fillCutFlow (); |
46 |
> |
// This causes the cut flow histograms to be filled. |
47 |
> |
cuts_->fillCutFlow (); |
48 |
|
|
49 |
< |
// Fill histograms while applying desired cuts. |
50 |
< |
for (vector<BNmuonCollection::const_iterator>::const_iterator muon1 = goodMuons.begin (); muon1 != goodMuons.end (); muon1++) |
49 |
> |
// Fill additional histograms while applying desired cuts. |
50 |
> |
if (cuts_->at ("oppositeSign")) |
51 |
|
{ |
52 |
< |
hists1D_["muonPT"]->Fill ((*muon1)->pt); |
69 |
< |
hists1D_["muonEta"]->Fill ((*muon1)->eta); |
70 |
< |
hists1D_["muonPhi"]->Fill ((*muon1)->phi); |
71 |
< |
for (vector<BNmuonCollection::const_iterator>::const_iterator muon2 = muon1 + 1; muon2 != goodMuons.end (); muon2++) |
52 |
> |
for (GoodMuonCollection::const_iterator goodMuon = goodMuons.begin (); goodMuon != goodMuons.end (); goodMuon++) |
53 |
|
{ |
54 |
< |
if ((*muon1)->charge * (*muon2)->charge > 0) |
55 |
< |
continue; |
56 |
< |
hists1D_["dimuonMass"]->Fill (dimuonMass (*muon1, *muon2)); |
54 |
> |
if (goodMuon->pass ("minPt")) |
55 |
> |
hists1D_["muonEta"]->Fill (goodMuon->eta); |
56 |
> |
if (goodMuon->pass ("maxEta")) |
57 |
> |
hists1D_["muonPt"]->Fill (goodMuon->pt); |
58 |
> |
if (goodMuon->pass ()) |
59 |
> |
hists1D_["muonPhi"]->Fill (goodMuon->phi); |
60 |
|
} |
61 |
+ |
hists1D_["dimuonMass"]->Fill (goodMuons.dimuonMass ()); |
62 |
|
} |
63 |
|
} |
64 |
|
|
80 |
– |
void |
81 |
– |
OSUAnalysis::selectGoodMuons (const edm::Handle<BNmuonCollection> &muons, vector<BNmuonCollection::const_iterator> &goodMuons) |
82 |
– |
{ |
83 |
– |
for (BNmuonCollection::const_iterator muon = muons->begin (); muon != muons->end (); muon++) |
84 |
– |
{ |
85 |
– |
if (fabs (muon->eta) > maxEta_) |
86 |
– |
continue; |
87 |
– |
if (muon->pt < minPt_) |
88 |
– |
continue; |
89 |
– |
goodMuons.push_back (muon); |
90 |
– |
} |
91 |
– |
} |
92 |
– |
|
93 |
– |
double |
94 |
– |
OSUAnalysis::dimuonMass (const BNmuonCollection::const_iterator &muon1, const BNmuonCollection::const_iterator &muon2) |
95 |
– |
{ |
96 |
– |
double dimuonE, dimuonPx, dimuonPy, dimuonPz; |
97 |
– |
|
98 |
– |
dimuonE = muon1->energy + muon2->energy; |
99 |
– |
dimuonPx = muon1->px + muon2->px; |
100 |
– |
dimuonPy = muon1->py + muon2->py; |
101 |
– |
dimuonPz = muon1->pz + muon2->pz; |
102 |
– |
|
103 |
– |
return sqrt (dimuonE * dimuonE - dimuonPx * dimuonPx - dimuonPy * dimuonPy - dimuonPz * dimuonPz); |
104 |
– |
} |
105 |
– |
|
106 |
– |
// Everything past this point can be broken off into a separate library. |
107 |
– |
|
108 |
– |
void |
109 |
– |
OSUAnalysis::fillCutFlow () |
110 |
– |
{ |
111 |
– |
|
112 |
– |
// Fills the cut flow histograms from the contents of cuts_. Three histograms |
113 |
– |
// are filled: cutFlow shows the number of events passing each cut, applied |
114 |
– |
// cumulatively; selection shows the number of events passing each cut, |
115 |
– |
// applied independently; and complementarySelection shows the number of |
116 |
– |
// events passing all but one cut. |
117 |
– |
|
118 |
– |
bool fillCumulative = true, fillComplement = true; |
119 |
– |
double complement = -1.0; |
120 |
– |
|
121 |
– |
hists1D_["cutFlow"]->Fill (0.5); |
122 |
– |
hists1D_["selection"]->Fill (0.5); |
123 |
– |
for (vector<string>::const_iterator cut = cutNames_.begin (); cut != cutNames_.end (); cut++) |
124 |
– |
{ |
125 |
– |
if (cuts_[*cut]) |
126 |
– |
{ |
127 |
– |
double binCenter = hists1D_["selection"]->GetBinCenter (cut - cutNames_.begin () + 2); |
128 |
– |
|
129 |
– |
hists1D_["selection"]->Fill (binCenter); |
130 |
– |
if (fillCumulative) |
131 |
– |
hists1D_["cutFlow"]->Fill (binCenter); |
132 |
– |
} |
133 |
– |
else |
134 |
– |
{ |
135 |
– |
fillCumulative = false; |
136 |
– |
if (complement < 0.0) |
137 |
– |
complement = hists1D_["complementarySelection"]->GetBinCenter (cut - cutNames_.begin () + 2); |
138 |
– |
else |
139 |
– |
fillComplement = false; |
140 |
– |
} |
141 |
– |
} |
142 |
– |
if (fillCumulative) |
143 |
– |
{ |
144 |
– |
hists1D_["complementarySelection"]->Fill (0.5); |
145 |
– |
for (vector<string>::const_iterator cut = cutNames_.begin (); cut != cutNames_.end (); cut++) |
146 |
– |
{ |
147 |
– |
double binCenter = hists1D_["complementarySelection"]->GetBinCenter (cut - cutNames_.begin () + 2); |
148 |
– |
|
149 |
– |
hists1D_["complementarySelection"]->Fill (binCenter); |
150 |
– |
} |
151 |
– |
} |
152 |
– |
if (!fillCumulative && fillComplement) |
153 |
– |
hists1D_["complementarySelection"]->Fill (complement); |
154 |
– |
} |
155 |
– |
|
156 |
– |
void |
157 |
– |
OSUAnalysis::outputTime () |
158 |
– |
{ |
159 |
– |
// Outputs the run time of the job, both CPU time and real time. |
160 |
– |
|
161 |
– |
double cpu, real; |
162 |
– |
int days, hours, minutes; |
163 |
– |
|
164 |
– |
cpu = sw_.CpuTime (); |
165 |
– |
real = sw_.RealTime (); |
166 |
– |
|
167 |
– |
days = (int) (cpu / (60.0 * 60.0 * 24.0)); |
168 |
– |
cpu -= days * (60.0 * 60.0 * 24.0); |
169 |
– |
hours = (int) (cpu / (60.0 * 60.0)); |
170 |
– |
cpu -= hours * (60.0 * 60.0); |
171 |
– |
minutes = (int) (cpu / 60.0); |
172 |
– |
cpu -= minutes * 60.0; |
173 |
– |
|
174 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
175 |
– |
cout << "CPU Time: "; |
176 |
– |
if (days) |
177 |
– |
cout << days << " days, "; |
178 |
– |
if (days || hours) |
179 |
– |
cout << hours << " hours, "; |
180 |
– |
if (days || hours || minutes) |
181 |
– |
cout << minutes << " minutes, "; |
182 |
– |
if (days || hours || minutes || cpu) |
183 |
– |
cout << cpu << " seconds" << endl; |
184 |
– |
|
185 |
– |
days = (int) (real / (60.0 * 60.0 * 24.0)); |
186 |
– |
real -= days * (60.0 * 60.0 * 24.0); |
187 |
– |
hours = (int) (real / (60.0 * 60.0)); |
188 |
– |
real -= hours * (60.0 * 60.0); |
189 |
– |
minutes = (int) (real / 60.0); |
190 |
– |
real -= minutes * 60.0; |
191 |
– |
|
192 |
– |
cout << "Real Time: "; |
193 |
– |
if (days) |
194 |
– |
cout << days << " days, "; |
195 |
– |
if (days || hours) |
196 |
– |
cout << hours << " hours, "; |
197 |
– |
if (days || hours || minutes) |
198 |
– |
cout << minutes << " minutes, "; |
199 |
– |
if (days || hours || minutes || cpu) |
200 |
– |
cout << real << " seconds" << endl; |
201 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
202 |
– |
} |
203 |
– |
|
204 |
– |
void |
205 |
– |
OSUAnalysis::outputCutFlow () |
206 |
– |
{ |
207 |
– |
// Outputs cut flow numbers from the histograms written to the output file. |
208 |
– |
|
209 |
– |
int totalEvents, totalEventsComplement; |
210 |
– |
|
211 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
212 |
– |
cout << setw (25) << left << "Cut Name" << right << setw (25) << "Cut Flow" << setw (25) << "Efficiency" << endl; |
213 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
214 |
– |
totalEvents = hists1D_["cutFlow"]->GetBinContent (1); |
215 |
– |
cout << setw (25) << left << "Total Events:" << right << setw (25) << totalEvents << setw (25) << "100%" << endl; |
216 |
– |
for (vector<string>::const_iterator cut = cutNames_.begin (); cut != cutNames_.end (); cut++) |
217 |
– |
{ |
218 |
– |
double cutFlow = hists1D_["cutFlow"]->GetBinContent (cut - cutNames_.begin () + 2); |
219 |
– |
|
220 |
– |
cout << setw (25) << left << (*cut + ":") << right << setw (25) << cutFlow << setw (24) << 100.0 * (cutFlow / (double) totalEvents) << "%" << endl; |
221 |
– |
} |
222 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
223 |
– |
|
224 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
225 |
– |
cout << setw (25) << left << "Cut Name" << right << setw (25) << "Selection" << setw (25) << "Efficiency" << endl; |
226 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
227 |
– |
cout << setw (25) << left << "Total Events:" << right << setw (25) << totalEvents << setw (25) << "100%" << endl; |
228 |
– |
for (vector<string>::const_iterator cut = cutNames_.begin (); cut != cutNames_.end (); cut++) |
229 |
– |
{ |
230 |
– |
double selection = hists1D_["selection"]->GetBinContent (cut - cutNames_.begin () + 2); |
231 |
– |
|
232 |
– |
cout << setw (25) << left << (*cut + ":") << right << setw (25) << selection << setw (24) << 100.0 * (selection / (double) totalEvents) << "%" << endl; |
233 |
– |
} |
234 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
235 |
– |
|
236 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
237 |
– |
cout << setw (25) << left << "Cut Name" << right << setw (25) << "Complementary Selection" << setw (25) << "Efficiency" << endl; |
238 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
239 |
– |
totalEventsComplement = hists1D_["complementarySelection"]->GetBinContent (1); |
240 |
– |
cout << setw (25) << left << "Total Events:" << right << setw (25) << totalEventsComplement << setw (24) << 100.0 * (totalEventsComplement / (double) totalEvents) << "%" << endl; |
241 |
– |
for (vector<string>::const_iterator cut = cutNames_.begin (); cut != cutNames_.end (); cut++) |
242 |
– |
{ |
243 |
– |
double complement = hists1D_["complementarySelection"]->GetBinContent (cut - cutNames_.begin () + 2); |
244 |
– |
|
245 |
– |
cout << setw (25) << left << (*cut + ":") << right << setw (25) << complement << setw (24) << 100.0 * (complement / (double) totalEvents) << "%" << endl; |
246 |
– |
} |
247 |
– |
cout << setw (75) << setfill ('-') << '-' << setfill (' ') << endl; |
248 |
– |
} |
249 |
– |
|
65 |
|
DEFINE_FWK_MODULE(OSUAnalysis); |